diff options
author | darkf <lw9k123@gmail.com> | 2014-12-30 04:47:41 +0100 |
---|---|---|
committer | darkf <lw9k123@gmail.com> | 2014-12-30 04:47:41 +0100 |
commit | 8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch) | |
tree | f1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/arm | |
parent | Add comment regarding __WIN32__ in SkyEye code (diff) | |
parent | Merge pull request #367 from bunnei/usat_ssat (diff) | |
download | yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.bz2 yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.lz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.zst yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip |
Diffstat (limited to 'src/core/arm')
22 files changed, 8501 insertions, 9156 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 3ae528562..3b7209418 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once @@ -78,6 +78,12 @@ public: virtual u64 GetTicks() const = 0; /** + * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) + * @param ticks Number of ticks to advance the CPU core + */ + virtual void AddTicks(u64 ticks) = 0; + + /** * Saves the current CPU context * @param ctx Thread context to save */ diff --git a/src/core/arm/disassembler/load_symbol_map.cpp b/src/core/arm/disassembler/load_symbol_map.cpp index 55278474b..13d26d170 100644 --- a/src/core/arm/disassembler/load_symbol_map.cpp +++ b/src/core/arm/disassembler/load_symbol_map.cpp @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include <string> diff --git a/src/core/arm/disassembler/load_symbol_map.h b/src/core/arm/disassembler/load_symbol_map.h index 837cca99b..d28c551c3 100644 --- a/src/core/arm/disassembler/load_symbol_map.h +++ b/src/core/arm/disassembler/load_symbol_map.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 6c8ea211e..a838fd25a 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include "core/arm/skyeye_common/armcpu.h" @@ -47,68 +47,38 @@ ARM_DynCom::ARM_DynCom() : ticks(0) { ARM_DynCom::~ARM_DynCom() { } -/** - * Set the Program Counter to an address - * @param addr Address to set PC to - */ void ARM_DynCom::SetPC(u32 pc) { state->pc = state->Reg[15] = pc; } -/* - * Get the current Program Counter - * @return Returns current PC - */ u32 ARM_DynCom::GetPC() const { return state->Reg[15]; } -/** - * Get an ARM register - * @param index Register index (0-15) - * @return Returns the value in the register - */ u32 ARM_DynCom::GetReg(int index) const { return state->Reg[index]; } -/** - * Set an ARM register - * @param index Register index (0-15) - * @param value Value to set register to - */ void ARM_DynCom::SetReg(int index, u32 value) { state->Reg[index] = value; } -/** - * Get the current CPSR register - * @return Returns the value of the CPSR register - */ u32 ARM_DynCom::GetCPSR() const { return state->Cpsr; } -/** - * Set the current CPSR register - * @param cpsr Value to set CPSR to - */ void ARM_DynCom::SetCPSR(u32 cpsr) { state->Cpsr = cpsr; } -/** - * Returns the number of clock ticks since the last reset - * @return Returns number of clock ticks - */ u64 ARM_DynCom::GetTicks() const { return ticks; } -/** - * Executes the given number of instructions - * @param num_instructions Number of instructions to executes - */ +void ARM_DynCom::AddTicks(u64 ticks) { + this->ticks += ticks; +} + void ARM_DynCom::ExecuteInstructions(int num_instructions) { state->NumInstrsToExecute = num_instructions; @@ -118,11 +88,6 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) { ticks += InterpreterMainLoop(state.get()); } -/** - * Saves the current CPU context - * @param ctx Thread context to save - * @todo Do we need to save Reg[15] and NextInstr? - */ void ARM_DynCom::SaveContext(ThreadContext& ctx) { memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); @@ -139,11 +104,6 @@ void ARM_DynCom::SaveContext(ThreadContext& ctx) { ctx.mode = state->NextInstr; } -/** - * Loads a CPU context - * @param ctx Thread context to load - * @param Do we need to load Reg[15] and NextInstr? - */ void ARM_DynCom::LoadContext(const ThreadContext& ctx) { memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); @@ -160,7 +120,6 @@ void ARM_DynCom::LoadContext(const ThreadContext& ctx) { state->NextInstr = ctx.mode; } -/// Prepare core for thread reschedule (if needed to correctly handle state) void ARM_DynCom::PrepareReschedule() { state->NumInstrsToExecute = 0; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 51eea41ed..7284dcd07 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once @@ -27,14 +27,14 @@ public: * Get the current Program Counter * @return Returns current PC */ - u32 GetPC() const; + u32 GetPC() const override; /** * Get an ARM register * @param index Register index (0-15) * @return Returns the value in the register */ - u32 GetReg(int index) const; + u32 GetReg(int index) const override; /** * Set an ARM register @@ -47,7 +47,7 @@ public: * Get the current CPSR register * @return Returns the value of the CPSR register */ - u32 GetCPSR() const; + u32 GetCPSR() const override; /** * Set the current CPSR register @@ -59,7 +59,13 @@ public: * Returns the number of clock ticks since the last reset * @return Returns number of clock ticks */ - u64 GetTicks() const; + u64 GetTicks() const override; + + /** + * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) + * @param ticks Number of ticks to advance the CPU core + */ + void AddTicks(u64 ticks) override; /** * Saves the current CPU context diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp index 5d174a08f..333b40f54 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.cpp +++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp @@ -1,402 +1,443 @@ -/* 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.cpp -* @brief Some common utility for arm decoder -* @author Michael.Kang blackfin.kang@gmail.com -* @version 7849 -* @date 2012-03-15 -*/ +// Copyright 2012 Michael Kang, 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/armdefs.h" #include "core/arm/dyncom/arm_dyncom_dec.h" const ISEITEM arm_instruction[] = { - #define VFP_DECODE - #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" - #undef VFP_DECODE - {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005}, - {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a}, - {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007}, - {"blx" , 1 , 3 , 25, 31, 0x0000007d}, - {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000}, - {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f}, - {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000}, - {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f}, - {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb}, - {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001}, - {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007}, - {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007}, - {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007}, - {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007}, - {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007}, - {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007}, - {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000}, - {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007}, - {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f}, - {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f}, - {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005}, - {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009}, - {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009}, - {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009}, - {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009}, - {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007}, - {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003}, - {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005}, - {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005}, - {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003}, - {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009}, - {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001}, - {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b}, - {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003}, - {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009}, - {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001}, - {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007}, - {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009}, - {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007}, - {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005}, - {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f}, - {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007}, - {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003}, - {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001}, - {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005}, - {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f}, - {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007}, - {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003}, - {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009}, - {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001}, - {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007}, - {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005}, - {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f}, - {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007}, - {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003}, - {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009}, - {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001}, - {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003}, - {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009}, - {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001}, - {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007}, - {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007}, - {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009}, - {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002}, - {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001}, - {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007}, - {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001}, - {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003}, - {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003}, - {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b}, - {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005}, - {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001}, - {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003}, - {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009}, - {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005}, - {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005}, - {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005}, - {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009}, - {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f}, - {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007}, - {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, - {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, - {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001}, - {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001}, - {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001}, - {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001}, - {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001}, - {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001}, - {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001}, - {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000}, - {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002}, - {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005}, - {"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}, - {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015}, - {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011}, - {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013}, - {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017}, - {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009}, - {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009}, - {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009}, - {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009}, - {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009}, - {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009}, - {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001}, - {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001}, - {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000}, - {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000}, - {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000}, - {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e}, - {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000}, - {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001}, - {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004}, - {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003}, - {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007}, - {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006}, - {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005}, - {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002}, - {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c}, - {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f}, - {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d}, - {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004}, - {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001}, - {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f}, - {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000}, - {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001}, - {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d}, - {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f}, - {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b}, - {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b}, - {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d}, - {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002}, - {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006}, - {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007}, - {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003}, - {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001}, - {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001}, - {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002}, - {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001}, - {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000}, - {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, - {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, - {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000}, - {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000}, - {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000}, - {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001}, - {"swi" , 1 , 0 , 24, 27, 0x0000000f}, - {"bbl" , 1 , 0 , 25, 27, 0x00000005}, + { "vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }, + { "vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }, + { "vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }, + { "vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, + { "vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, + { "vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, + { "vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, + { "vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, + { "vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, + { "vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, + { "vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0 }, + { "vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }, + { "vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, + { "vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }, + { "vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, + { "vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, + { "vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40 }, + { "vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, + { "vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 5, 6, 6, 1 }, + { "vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, + { "vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10 }, + { "vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10 }, + { "vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0, 4, 0x10 }, + { "vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10 }, + { "vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0, 4, 0x10 }, + { "vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1 }, + { "vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1 }, + { "vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11, 5 }, + { "vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11, 5 }, + { "vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 5 }, + { "vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11, 5 }, + { "vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11, 5 }, + { "vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 5 }, + + { "srs", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005 }, + { "rfe", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a }, + { "bkpt", 2, 3, 20, 31, 0x00000e12, 4, 7, 0x00000007 }, + { "blx", 1, 3, 25, 31, 0x0000007d }, + { "cps", 3, 6, 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000 }, + { "pld", 4, 4, 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f }, + { "setend", 2, 6, 16, 31, 0x0000f101, 4, 7, 0x00000000 }, + { "clrex", 1, 6, 0, 31, 0xf57ff01f }, + { "rev16", 2, 6, 16, 27, 0x000006bf, 4, 11, 0x000000fb }, + { "usad8", 3, 6, 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001 }, + { "sxtb", 2, 6, 16, 27, 0x000006af, 4, 7, 0x00000007 }, + { "uxtb", 2, 6, 16, 27, 0x000006ef, 4, 7, 0x00000007 }, + { "sxth", 2, 6, 16, 27, 0x000006bf, 4, 7, 0x00000007 }, + { "sxtb16", 2, 6, 16, 27, 0x0000068f, 4, 7, 0x00000007 }, + { "uxth", 2, 6, 16, 27, 0x000006ff, 4, 7, 0x00000007 }, + { "uxtb16", 2, 6, 16, 27, 0x000006cf, 4, 7, 0x00000007 }, + { "cpy", 2, 6, 20, 27, 0x0000001a, 4, 11, 0x00000000 }, + { "uxtab", 2, 6, 20, 27, 0x0000006e, 4, 9, 0x00000007 }, + { "ssub8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x0000000f }, + { "shsub8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x0000000f }, + { "ssubaddx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000005 }, + { "strex", 2, 6, 20, 27, 0x00000018, 4, 7, 0x00000009 }, + { "strexb", 2, 7, 20, 27, 0x0000001c, 4, 7, 0x00000009 }, + { "swp", 2, 0, 20, 27, 0x00000010, 4, 7, 0x00000009 }, + { "swpb", 2, 0, 20, 27, 0x00000014, 4, 7, 0x00000009 }, + { "ssub16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000007 }, + { "ssat16", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000003 }, + { "shsubaddx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000005 }, + { "qsubaddx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000005 }, + { "shaddsubx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000003 }, + { "shadd8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000009 }, + { "shadd16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000001 }, + { "sel", 2, 6, 20, 27, 0x00000068, 4, 7, 0x0000000b }, + { "saddsubx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000003 }, + { "sadd8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000009 }, + { "sadd16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000001 }, + { "shsub16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000007 }, + { "umaal", 2, 6, 20, 27, 0x00000004, 4, 7, 0x00000009 }, + { "uxtab16", 2, 6, 20, 27, 0x0000006c, 4, 7, 0x00000007 }, + { "usubaddx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000005 }, + { "usub8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x0000000f }, + { "usub16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000007 }, + { "usat16", 2, 6, 20, 27, 0x0000006e, 4, 7, 0x00000003 }, + { "usada8", 2, 6, 20, 27, 0x00000078, 4, 7, 0x00000001 }, + { "uqsubaddx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000005 }, + { "uqsub8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x0000000f }, + { "uqsub16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000007 }, + { "uqaddsubx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000003 }, + { "uqadd8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000009 }, + { "uqadd16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000001 }, + { "sxtab", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000007 }, + { "uhsubaddx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000005 }, + { "uhsub8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x0000000f }, + { "uhsub16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000007 }, + { "uhaddsubx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000003 }, + { "uhadd8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000009 }, + { "uhadd16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000001 }, + { "uaddsubx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000003 }, + { "uadd8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000009 }, + { "uadd16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000001 }, + { "sxtah", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000007 }, + { "sxtab16", 2, 6, 20, 27, 0x00000068, 4, 7, 0x00000007 }, + { "qadd8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000009 }, + { "bxj", 2, 5, 20, 27, 0x00000012, 4, 7, 0x00000002 }, + { "clz", 2, 3, 20, 27, 0x00000016, 4, 7, 0x00000001 }, + { "uxtah", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x00000007 }, + { "bx", 2, 2, 20, 27, 0x00000012, 4, 7, 0x00000001 }, + { "rev", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000003 }, + { "blx", 2, 3, 20, 27, 0x00000012, 4, 7, 0x00000003 }, + { "revsh", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x0000000b }, + { "qadd", 2, 4, 20, 27, 0x00000010, 4, 7, 0x00000005 }, + { "qadd16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000001 }, + { "qaddsubx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000003 }, + { "ldrex", 2, 0, 20, 27, 0x00000019, 4, 7, 0x00000009 }, + { "qdadd", 2, 4, 20, 27, 0x00000014, 4, 7, 0x00000005 }, + { "qdsub", 2, 4, 20, 27, 0x00000016, 4, 7, 0x00000005 }, + { "qsub", 2, 4, 20, 27, 0x00000012, 4, 7, 0x00000005 }, + { "ldrexb", 2, 7, 20, 27, 0x0000001d, 4, 7, 0x00000009 }, + { "qsub8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x0000000f }, + { "qsub16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000007 }, + { "smuad", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }, + { "smmul", 4, 6, 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }, + { "smusd", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001 }, + { "smlsd", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001 }, + { "smlsld", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001 }, + { "smmla", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001 }, + { "smmls", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001 }, + { "smlald", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001 }, + { "smlad", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001 }, + { "smlaw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000 }, + { "smulw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002 }, + { "pkhtb", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000005 }, + { "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 }, + { "cmp", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000015 }, + { "tst", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000011 }, + { "teq", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000013 }, + { "cmn", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000017 }, + { "smull", 2, 0, 21, 27, 0x00000006, 4, 7, 0x00000009 }, + { "umull", 2, 0, 21, 27, 0x00000004, 4, 7, 0x00000009 }, + { "umlal", 2, 0, 21, 27, 0x00000005, 4, 7, 0x00000009 }, + { "smlal", 2, 0, 21, 27, 0x00000007, 4, 7, 0x00000009 }, + { "mul", 2, 0, 21, 27, 0x00000000, 4, 7, 0x00000009 }, + { "mla", 2, 0, 21, 27, 0x00000001, 4, 7, 0x00000009 }, + { "ssat", 2, 6, 21, 27, 0x00000035, 4, 5, 0x00000001 }, + { "usat", 2, 6, 21, 27, 0x00000037, 4, 5, 0x00000001 }, + { "mrs", 4, 0, 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000 }, + { "msr", 3, 0, 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000 }, + { "and", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000000 }, + { "bic", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000e }, + { "ldm", 3, 0, 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000 }, + { "eor", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000001 }, + { "add", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000004 }, + { "rsb", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000003 }, + { "rsc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000007 }, + { "sbc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000006 }, + { "adc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000005 }, + { "sub", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000002 }, + { "orr", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000c }, + { "mvn", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000f }, + { "mov", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000d }, + { "stm", 2, 0, 25, 27, 0x00000004, 20, 22, 0x00000004 }, + { "ldm", 4, 0, 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001 }, + { "ldrsh", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f }, + { "stm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000 }, + { "ldm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001 }, + { "ldrsb", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d }, + { "strd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f }, + { "ldrh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b }, + { "strh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b }, + { "ldrd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d }, + { "strt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002 }, + { "strbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006 }, + { "ldrbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007 }, + { "ldrt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003 }, + { "mrc", 3, 6, 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001 }, + { "mcr", 3, 0, 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001 }, + { "msr", 2, 0, 23, 27, 0x00000006, 20, 21, 0x00000002 }, + { "ldrb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001 }, + { "strb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000 }, + { "ldr", 4, 0, 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }, + { "ldrcond", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }, + { "str", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000 }, + { "cdp", 2, 0, 24, 27, 0x0000000e, 4, 4, 0x00000000 }, + { "stc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000000 }, + { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, + { "swi", 1, 0, 24, 27, 0x0000000f }, + { "bbl", 1, 0, 25, 27, 0x00000005 }, }; const ISEITEM arm_exclusion_code[] = { - #define VFP_DECODE_EXCLUSION - #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" - #undef VFP_DECODE_EXCLUSION - {"srs" , 0 , 6 , 0}, - {"rfe" , 0 , 6 , 0}, - {"bkpt" , 0 , 3 , 0}, - {"blx" , 0 , 3 , 0}, - {"cps" , 0 , 6 , 0}, - {"pld" , 0 , 4 , 0}, - {"setend" , 0 , 6 , 0}, - {"clrex" , 0 , 6 , 0}, - {"rev16" , 0 , 6 , 0}, - {"usad8" , 0 , 6 , 0}, - {"sxtb" , 0 , 6 , 0}, - {"uxtb" , 0 , 6 , 0}, - {"sxth" , 0 , 6 , 0}, - {"sxtb16" , 0 , 6 , 0}, - {"uxth" , 0 , 6 , 0}, - {"uxtb16" , 0 , 6 , 0}, - {"cpy" , 0 , 6 , 0}, - {"uxtab" , 0 , 6 , 0}, - {"ssub8" , 0 , 6 , 0}, - {"shsub8" , 0 , 6 , 0}, - {"ssubaddx" , 0 , 6 , 0}, - {"strex" , 0 , 6 , 0}, - {"strexb" , 0 , 7 , 0}, - {"swp" , 0 , 0 , 0}, - {"swpb" , 0 , 0 , 0}, - {"ssub16" , 0 , 6 , 0}, - {"ssat16" , 0 , 6 , 0}, - {"shsubaddx" , 0 , 6 , 0}, - {"qsubaddx" , 0 , 6 , 0}, - {"shaddsubx" , 0 , 6 , 0}, - {"shadd8" , 0 , 6 , 0}, - {"shadd16" , 0 , 6 , 0}, - {"sel" , 0 , 6 , 0}, - {"saddsubx" , 0 , 6 , 0}, - {"sadd8" , 0 , 6 , 0}, - {"sadd16" , 0 , 6 , 0}, - {"shsub16" , 0 , 6 , 0}, - {"umaal" , 0 , 6 , 0}, - {"uxtab16" , 0 , 6 , 0}, - {"usubaddx" , 0 , 6 , 0}, - {"usub8" , 0 , 6 , 0}, - {"usub16" , 0 , 6 , 0}, - {"usat16" , 0 , 6 , 0}, - {"usada8" , 0 , 6 , 0}, - {"uqsubaddx" , 0 , 6 , 0}, - {"uqsub8" , 0 , 6 , 0}, - {"uqsub16" , 0 , 6 , 0}, - {"uqaddsubx" , 0 , 6 , 0}, - {"uqadd8" , 0 , 6 , 0}, - {"uqadd16" , 0 , 6 , 0}, - {"sxtab" , 0 , 6 , 0}, - {"uhsubaddx" , 0 , 6 , 0}, - {"uhsub8" , 0 , 6 , 0}, - {"uhsub16" , 0 , 6 , 0}, - {"uhaddsubx" , 0 , 6 , 0}, - {"uhadd8" , 0 , 6 , 0}, - {"uhadd16" , 0 , 6 , 0}, - {"uaddsubx" , 0 , 6 , 0}, - {"uadd8" , 0 , 6 , 0}, - {"uadd16" , 0 , 6 , 0}, - {"sxtah" , 0 , 6 , 0}, - {"sxtab16" , 0 , 6 , 0}, - {"qadd8" , 0 , 6 , 0}, - {"bxj" , 0 , 5 , 0}, - {"clz" , 0 , 3 , 0}, - {"uxtah" , 0 , 6 , 0}, - {"bx" , 0 , 2 , 0}, - {"rev" , 0 , 6 , 0}, - {"blx" , 0 , 3 , 0}, - {"revsh" , 0 , 6 , 0}, - {"qadd" , 0 , 4 , 0}, - {"qadd16" , 0 , 6 , 0}, - {"qaddsubx" , 0 , 6 , 0}, - {"ldrex" , 0 , 0 , 0}, - {"qdadd" , 0 , 4 , 0}, - {"qdsub" , 0 , 4 , 0}, - {"qsub" , 0 , 4 , 0}, - {"ldrexb" , 0 , 7 , 0}, - {"qsub8" , 0 , 6 , 0}, - {"qsub16" , 0 , 6 , 0}, - {"smuad" , 0 , 6 , 0}, - {"smmul" , 0 , 6 , 0}, - {"smusd" , 0 , 6 , 0}, - {"smlsd" , 0 , 6 , 0}, - {"smlsld" , 0 , 6 , 0}, - {"smmla" , 0 , 6 , 0}, - {"smmls" , 0 , 6 , 0}, - {"smlald" , 0 , 6 , 0}, - {"smlad" , 0 , 6 , 0}, - {"smlaw" , 0 , 4 , 0}, - {"smulw" , 0 , 4 , 0}, - {"pkhtb" , 0 , 6 , 0}, - {"pkhbt" , 0 , 6 , 0}, - {"smul" , 0 , 4 , 0}, - {"smlal" , 0 , 4 , 0}, - {"smla" , 0 , 4 , 0}, - {"mcrr" , 0 , 6 , 0}, - {"mrrc" , 0 , 6 , 0}, - {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"smull" , 0 , 0 , 0}, - {"umull" , 0 , 0 , 0}, - {"umlal" , 0 , 0 , 0}, - {"smlal" , 0 , 0 , 0}, - {"mul" , 0 , 0 , 0}, - {"mla" , 0 , 0 , 0}, - {"ssat" , 0 , 6 , 0}, - {"usat" , 0 , 6 , 0}, - {"mrs" , 0 , 0 , 0}, - {"msr" , 0 , 0 , 0}, - {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"ldm" , 0 , 0 , 0}, - {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, - {"stm" , 0 , 0 , 0}, - {"ldm" , 0 , 0 , 0}, - {"ldrsh" , 0 , 2 , 0}, - {"stm" , 0 , 0 , 0}, - {"ldm" , 0 , 0 , 0}, - {"ldrsb" , 0 , 2 , 0}, - {"strd" , 0 , 4 , 0}, - {"ldrh" , 0 , 0 , 0}, - {"strh" , 0 , 0 , 0}, - {"ldrd" , 0 , 4 , 0}, - {"strt" , 0 , 0 , 0}, - {"strbt" , 0 , 0 , 0}, - {"ldrbt" , 0 , 0 , 0}, - {"ldrt" , 0 , 0 , 0}, - {"mrc" , 0 , 6 , 0}, - {"mcr" , 0 , 0 , 0}, - {"msr" , 0 , 0 , 0}, - {"ldrb" , 0 , 0 , 0}, - {"strb" , 0 , 0 , 0}, - {"ldr" , 0 , 0 , 0}, - {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e}, - {"str" , 0 , 0 , 0}, - {"cdp" , 0 , 0 , 0}, - {"stc" , 0 , 0 , 0}, - {"ldc" , 0 , 0 , 0}, - {"swi" , 0 , 0 , 0}, - {"bbl" , 0 , 0 , 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] */ - {"invalid", 0, INVALID, 0} + { "vmla", 0, ARMVFP2, 0 }, + { "vmls", 0, ARMVFP2, 0 }, + { "vnmla", 0, ARMVFP2, 0 }, + { "vnmla", 0, ARMVFP2, 0 }, + { "vnmls", 0, ARMVFP2, 0 }, + { "vnmul", 0, ARMVFP2, 0 }, + { "vmul", 0, ARMVFP2, 0 }, + { "vadd", 0, ARMVFP2, 0 }, + { "vsub", 0, ARMVFP2, 0 }, + { "vdiv", 0, ARMVFP2, 0 }, + { "vmov(i)", 0, ARMVFP3, 0 }, + { "vmov(r)", 0, ARMVFP3, 0 }, + { "vabs", 0, ARMVFP2, 0 }, + { "vneg", 0, ARMVFP2, 0 }, + { "vsqrt", 0, ARMVFP2, 0 }, + { "vcmp", 0, ARMVFP2, 0 }, + { "vcmp2", 0, ARMVFP2, 0 }, + { "vcvt(bff)", 0, ARMVFP3, 4, 4, 1 }, + { "vcvt(bds)", 0, ARMVFP2, 0 }, + { "vcvt(bfi)", 0, ARMVFP2, 0 }, + { "vmovbrs", 0, ARMVFP2, 0 }, + { "vmsr", 0, ARMVFP2, 0 }, + { "vmovbrc", 0, ARMVFP2, 0 }, + { "vmrs", 0, ARMVFP2, 0 }, + { "vmovbcr", 0, ARMVFP2, 0 }, + { "vmovbrrss", 0, ARMVFP2, 0 }, + { "vmovbrrd", 0, ARMVFP2, 0 }, + { "vstr", 0, ARMVFP2, 0 }, + { "vpush", 0, ARMVFP2, 0 }, + { "vstm", 0, ARMVFP2, 0 }, + { "vpop", 0, ARMVFP2, 0 }, + { "vldr", 0, ARMVFP2, 0 }, + { "vldm", 0, ARMVFP2, 0 }, + + { "srs", 0, 6, 0 }, + { "rfe", 0, 6, 0 }, + { "bkpt", 0, 3, 0 }, + { "blx", 0, 3, 0 }, + { "cps", 0, 6, 0 }, + { "pld", 0, 4, 0 }, + { "setend", 0, 6, 0 }, + { "clrex", 0, 6, 0 }, + { "rev16", 0, 6, 0 }, + { "usad8", 0, 6, 0 }, + { "sxtb", 0, 6, 0 }, + { "uxtb", 0, 6, 0 }, + { "sxth", 0, 6, 0 }, + { "sxtb16", 0, 6, 0 }, + { "uxth", 0, 6, 0 }, + { "uxtb16", 0, 6, 0 }, + { "cpy", 0, 6, 0 }, + { "uxtab", 0, 6, 0 }, + { "ssub8", 0, 6, 0 }, + { "shsub8", 0, 6, 0 }, + { "ssubaddx", 0, 6, 0 }, + { "strex", 0, 6, 0 }, + { "strexb", 0, 7, 0 }, + { "swp", 0, 0, 0 }, + { "swpb", 0, 0, 0 }, + { "ssub16", 0, 6, 0 }, + { "ssat16", 0, 6, 0 }, + { "shsubaddx", 0, 6, 0 }, + { "qsubaddx", 0, 6, 0 }, + { "shaddsubx", 0, 6, 0 }, + { "shadd8", 0, 6, 0 }, + { "shadd16", 0, 6, 0 }, + { "sel", 0, 6, 0 }, + { "saddsubx", 0, 6, 0 }, + { "sadd8", 0, 6, 0 }, + { "sadd16", 0, 6, 0 }, + { "shsub16", 0, 6, 0 }, + { "umaal", 0, 6, 0 }, + { "uxtab16", 0, 6, 0 }, + { "usubaddx", 0, 6, 0 }, + { "usub8", 0, 6, 0 }, + { "usub16", 0, 6, 0 }, + { "usat16", 0, 6, 0 }, + { "usada8", 0, 6, 0 }, + { "uqsubaddx", 0, 6, 0 }, + { "uqsub8", 0, 6, 0 }, + { "uqsub16", 0, 6, 0 }, + { "uqaddsubx", 0, 6, 0 }, + { "uqadd8", 0, 6, 0 }, + { "uqadd16", 0, 6, 0 }, + { "sxtab", 0, 6, 0 }, + { "uhsubaddx", 0, 6, 0 }, + { "uhsub8", 0, 6, 0 }, + { "uhsub16", 0, 6, 0 }, + { "uhaddsubx", 0, 6, 0 }, + { "uhadd8", 0, 6, 0 }, + { "uhadd16", 0, 6, 0 }, + { "uaddsubx", 0, 6, 0 }, + { "uadd8", 0, 6, 0 }, + { "uadd16", 0, 6, 0 }, + { "sxtah", 0, 6, 0 }, + { "sxtab16", 0, 6, 0 }, + { "qadd8", 0, 6, 0 }, + { "bxj", 0, 5, 0 }, + { "clz", 0, 3, 0 }, + { "uxtah", 0, 6, 0 }, + { "bx", 0, 2, 0 }, + { "rev", 0, 6, 0 }, + { "blx", 0, 3, 0 }, + { "revsh", 0, 6, 0 }, + { "qadd", 0, 4, 0 }, + { "qadd16", 0, 6, 0 }, + { "qaddsubx", 0, 6, 0 }, + { "ldrex", 0, 0, 0 }, + { "qdadd", 0, 4, 0 }, + { "qdsub", 0, 4, 0 }, + { "qsub", 0, 4, 0 }, + { "ldrexb", 0, 7, 0 }, + { "qsub8", 0, 6, 0 }, + { "qsub16", 0, 6, 0 }, + { "smuad", 0, 6, 0 }, + { "smmul", 0, 6, 0 }, + { "smusd", 0, 6, 0 }, + { "smlsd", 0, 6, 0 }, + { "smlsld", 0, 6, 0 }, + { "smmla", 0, 6, 0 }, + { "smmls", 0, 6, 0 }, + { "smlald", 0, 6, 0 }, + { "smlad", 0, 6, 0 }, + { "smlaw", 0, 4, 0 }, + { "smulw", 0, 4, 0 }, + { "pkhtb", 0, 6, 0 }, + { "pkhbt", 0, 6, 0 }, + { "smul", 0, 4, 0 }, + { "smlal", 0, 4, 0 }, + { "smla", 0, 4, 0 }, + { "mcrr", 0, 6, 0 }, + { "mrrc", 0, 6, 0 }, + { "cmp", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "tst", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "teq", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "cmn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "smull", 0, 0, 0 }, + { "umull", 0, 0, 0 }, + { "umlal", 0, 0, 0 }, + { "smlal", 0, 0, 0 }, + { "mul", 0, 0, 0 }, + { "mla", 0, 0, 0 }, + { "ssat", 0, 6, 0 }, + { "usat", 0, 6, 0 }, + { "mrs", 0, 0, 0 }, + { "msr", 0, 0, 0 }, + { "and", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "bic", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "ldm", 0, 0, 0 }, + { "eor", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "add", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "rsb", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "rsc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "sbc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "adc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "sub", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "orr", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "mvn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "mov", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, + { "stm", 0, 0, 0 }, + { "ldm", 0, 0, 0 }, + { "ldrsh", 0, 2, 0 }, + { "stm", 0, 0, 0 }, + { "ldm", 0, 0, 0 }, + { "ldrsb", 0, 2, 0 }, + { "strd", 0, 4, 0 }, + { "ldrh", 0, 0, 0 }, + { "strh", 0, 0, 0 }, + { "ldrd", 0, 4, 0 }, + { "strt", 0, 0, 0 }, + { "strbt", 0, 0, 0 }, + { "ldrbt", 0, 0, 0 }, + { "ldrt", 0, 0, 0 }, + { "mrc", 0, 6, 0 }, + { "mcr", 0, 0, 0 }, + { "msr", 0, 0, 0 }, + { "ldrb", 0, 0, 0 }, + { "strb", 0, 0, 0 }, + { "ldr", 0, 0, 0 }, + { "ldrcond", 1, 0, 28, 31, 0x0000000e }, + { "str", 0, 0, 0 }, + { "cdp", 0, 0, 0 }, + { "stc", 0, 0, 0 }, + { "ldc", 0, 0, 0 }, + { "swi", 0, 0, 0 }, + { "bbl", 0, 0, 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] + { "invalid", 0, INVALID, 0 } }; -int decode_arm_instr(uint32_t instr, int32_t *idx) -{ - int n = 0; - int base = 0; - int ret = DECODE_FAILURE; - int i = 0; - int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM); - for (i = 0; i < instr_slots; i++) - { -// ret = DECODE_SUCCESS; - n = arm_instruction[i].attribute_value; - base = 0; - while (n) { - if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { - /* clrex */ - if (instr != arm_instruction[i].content[base + 2]) { - break; - } - } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { - break; - } - base += 3; - n --; - } - //All conditions is satisfied. - if (n == 0) - ret = DECODE_SUCCESS; +int decode_arm_instr(uint32_t instr, int32_t *idx) { + int n = 0; + int base = 0; + 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; - if (ret == DECODE_SUCCESS) { - n = arm_exclusion_code[i].attribute_value; - if (n != 0) { - base = 0; - while (n) { - if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { - break; } - base += 3; - n --; - } - //All conditions is satisfied. - if (n == 0) - ret = DECODE_FAILURE; - } - } + while (n) { + if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { + // clrex + if (instr != arm_instruction[i].content[base + 2]) { + break; + } + } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { + break; + } + base += 3; + n--; + } - if (ret == DECODE_SUCCESS) { - *idx = i; - return ret; - } - } - return ret; -} + // All conditions is satisfied. + if (n == 0) + ret = DECODE_SUCCESS; + if (ret == DECODE_SUCCESS) { + n = arm_exclusion_code[i].attribute_value; + if (n != 0) { + base = 0; + while (n) { + if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { + break; + } + base += 3; + n--; + } + + // All conditions is satisfied. + if (n == 0) + ret = DECODE_FAILURE; + } + } + + if (ret == DECODE_SUCCESS) { + *idx = i; + return ret; + } + } + return ret; +} diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h index 19d94f369..70eb96e93 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.h +++ b/src/core/arm/dyncom/arm_dyncom_dec.h @@ -56,8 +56,6 @@ #define RN ((instr >> 16) & 0xF) /*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */ #define RM (instr & 0xF) -#define BIT(n) ((instr >> (n)) & 1) -#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) /* CP15 registers */ #define OPCODE_1 BITS(21, 23) diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 37925e8a8..53da7ca9c 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -1,32 +1,11 @@ -/* 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_interpreter.cpp -* @brief The fast interpreter for arm -* @author Michael.Kang blackfin.kang@gmail.com -* @version 7849 -* @date 2012-03-15 -*/ +// Copyright 2012 Michael Kang, 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. #define CITRA_IGNORE_EXIT(x) #include <algorithm> -#include <map> +#include <unordered_map> #include <stdio.h> #include <assert.h> #include <cstdio> @@ -47,10 +26,6 @@ using namespace std; #include "arm_dyncom_thumb.h" #include "arm_dyncom_run.h" #include "core/arm/skyeye_common/vfp/vfp.h" -/* shenoubang 2012-6-14 */ -#ifdef __WIN32__ -#include "bank_defs.h" -#endif #include "core/mem_map.h" #include "core/hle/hle.h" @@ -66,327 +41,243 @@ enum { THUMB = (1 << 7) }; -#define USER_MODE_OPT 1 -#define HYBRID_MODE 0 // Enable for JIT mode +#define USER_MODE_OPT 1 +#define HYBRID_MODE 0 // Enable for JIT mode -#define THRESHOLD 1000 -#define DURATION 500 -//#define PRINT_PROFILE_INFO +#define THRESHOLD 1000 +#define DURATION 500 -#define CHECK_RS if(RS == 15) rs += 8 -#define CHECK_RM if(RM == 15) rm += 8 +#define CHECK_RS if(RS == 15) rs += 8 +#define CHECK_RM if(RM == 15) rm += 8 -//#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1)) #undef BITS #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) #define BIT(s, n) ((s >> (n)) & 1) -#define RM BITS(sht_oper, 0, 3) -#define RS BITS(sht_oper, 8, 11) - -#define glue(x, y) x ## y -#define DPO(s) glue(DataProcessingOperands, s) -#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) -#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) -#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) -#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) - -//#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n)))) -//#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1))) +#define RM BITS(sht_oper, 0, 3) +#define RS BITS(sht_oper, 8, 11) + +#define glue(x, y) x ## y +#define DPO(s) glue(DataProcessingOperands, s) +#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) +#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) +#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) +#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) + #define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) extern void switch_mode(arm_core_t *core, uint32_t mode); -//extern bool InAPrivilegedMode(arm_core_t *core); typedef arm_core_t arm_processor; typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); -/* exclusive memory access */ +// Exclusive memory access static int exclusive_detect(ARMul_State* state, ARMword addr){ - int i; - #if 0 - for(i = 0; i < 128; i++){ - if(state->exclusive_tag_array[i] == addr) - return 0; - } - #endif - if(state->exclusive_tag == addr) - return 0; - else - return -1; + if(state->exclusive_tag == addr) + return 0; + else + return -1; } static void add_exclusive_addr(ARMul_State* state, ARMword addr){ - int i; - #if 0 - for(i = 0; i < 128; i++){ - if(state->exclusive_tag_array[i] == 0xffffffff){ - state->exclusive_tag_array[i] = addr; - //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr); - return; - } - } - DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__); - #endif - state->exclusive_tag = addr; - return; + state->exclusive_tag = addr; + return; } static void remove_exclusive(ARMul_State* state, ARMword addr){ - #if 0 - int i; - for(i = 0; i < 128; i++){ - if(state->exclusive_tag_array[i] == addr){ - state->exclusive_tag_array[i] = 0xffffffff; - //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr); - return; - } - } - #endif - state->exclusive_tag = 0xFFFFFFFF; -} - - -unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - unsigned int immed_8 = BITS(sht_oper, 0, 7); - unsigned int rotate_imm = BITS(sht_oper, 8, 11); -// DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8); -// DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm); - unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2); -// DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand); - /* set c flag */ - if (rotate_imm == 0) - cpu->shifter_carry_out = cpu->CFlag; - else - cpu->shifter_carry_out = BIT(shifter_operand, 31); - return shifter_operand; -} - -unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RM == 15) rm += 8; - unsigned int shifter_operand = rm; - cpu->shifter_carry_out = cpu->CFlag; - return shifter_operand; + state->exclusive_tag = 0xFFFFFFFF; +} + + +unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int immed_8 = BITS(sht_oper, 0, 7); + unsigned int rotate_imm = BITS(sht_oper, 8, 11); + unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2); + if (rotate_imm == 0) + cpu->shifter_carry_out = cpu->CFlag; + else + cpu->shifter_carry_out = BIT(shifter_operand, 31); + return shifter_operand; +} + +unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int shifter_operand = rm; + cpu->shifter_carry_out = cpu->CFlag; + return shifter_operand; +} + +unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) { + int shift_imm = BITS(sht_oper, 7, 11); + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int shifter_operand; + if (shift_imm == 0) { + shifter_operand = rm; + cpu->shifter_carry_out = cpu->CFlag; + } else { + shifter_operand = rm << shift_imm; + cpu->shifter_carry_out = BIT(rm, 32 - shift_imm); + } + return shifter_operand; +} + +unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) { + int shifter_operand; + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int rs = CHECK_READ_REG15(cpu, RS); + if (BITS(rs, 0, 7) == 0) { + shifter_operand = rm; + cpu->shifter_carry_out = cpu->CFlag; + } else if (BITS(rs, 0, 7) < 32) { + shifter_operand = rm << BITS(rs, 0, 7); + cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7)); + } else if (BITS(rs, 0, 7) == 32) { + shifter_operand = 0; + cpu->shifter_carry_out = BIT(rm, 0); + } else { + shifter_operand = 0; + cpu->shifter_carry_out = 0; + } + return shifter_operand; +} + +unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int shifter_operand; + int shift_imm = BITS(sht_oper, 7, 11); + if (shift_imm == 0) { + shifter_operand = 0; + cpu->shifter_carry_out = BIT(rm, 31); + } else { + shifter_operand = rm >> shift_imm; + cpu->shifter_carry_out = BIT(rm, shift_imm - 1); + } + return shifter_operand; +} + +unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int rs = CHECK_READ_REG15(cpu, RS); + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int shifter_operand; + if (BITS(rs, 0, 7) == 0) { + shifter_operand = rm; + cpu->shifter_carry_out = cpu->CFlag; + } else if (BITS(rs, 0, 7) < 32) { + shifter_operand = rm >> BITS(rs, 0, 7); + cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); + } else if (BITS(rs, 0, 7) == 32) { + shifter_operand = 0; + cpu->shifter_carry_out = BIT(rm, 31); + } else { + shifter_operand = 0; + cpu->shifter_carry_out = 0; + } + return shifter_operand; +} + +unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int shifter_operand; + int shift_imm = BITS(sht_oper, 7, 11); + if (shift_imm == 0) { + if (BIT(rm, 31)) { + shifter_operand = 0; + cpu->shifter_carry_out = BIT(rm, 31); + } else { + shifter_operand = 0xFFFFFFFF; + cpu->shifter_carry_out = BIT(rm, 31); + } + } else { + shifter_operand = static_cast<int>(rm) >> shift_imm; + cpu->shifter_carry_out = BIT(rm, shift_imm - 1); + } + return shifter_operand; +} + +unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int rs = CHECK_READ_REG15(cpu, RS); + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int shifter_operand; + if (BITS(rs, 0, 7) == 0) { + shifter_operand = rm; + cpu->shifter_carry_out = cpu->CFlag; + } else if (BITS(rs, 0, 7) < 32) { + shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7); + cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); + } else { + if (BIT(rm, 31) == 0) + shifter_operand = 0; + else + shifter_operand = 0xffffffff; + cpu->shifter_carry_out = BIT(rm, 31); + } + return shifter_operand; +} + +unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int shifter_operand; + unsigned int rm = CHECK_READ_REG15(cpu, RM); + int shift_imm = BITS(sht_oper, 7, 11); + if (shift_imm == 0) { + shifter_operand = (cpu->CFlag << 31) | (rm >> 1); + cpu->shifter_carry_out = BIT(rm, 0); + } else { + shifter_operand = ROTATE_RIGHT_32(rm, shift_imm); + cpu->shifter_carry_out = BIT(rm, shift_imm - 1); + } + return shifter_operand; +} + +unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { + unsigned int rm = CHECK_READ_REG15(cpu, RM); + unsigned int rs = CHECK_READ_REG15(cpu, RS); + unsigned int shifter_operand; + if (BITS(rs, 0, 7) == 0) { + shifter_operand = rm; + cpu->shifter_carry_out = cpu->CFlag; + } else if (BITS(rs, 0, 4) == 0) { + shifter_operand = rm; + cpu->shifter_carry_out = BIT(rm, 31); + } else { + shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4)); + cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1); + } + return shifter_operand; } -unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - int shift_imm = BITS(sht_oper, 7, 11); - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RM == 15) rm += 8; - unsigned int shifter_operand; - if (shift_imm == 0) { - shifter_operand = rm; - cpu->shifter_carry_out = cpu->CFlag; - } else { - shifter_operand = rm << shift_imm; - cpu->shifter_carry_out = BIT(rm, 32 - shift_imm); - } - return shifter_operand; -} - -unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - int shifter_operand; - unsigned int rm = CHECK_READ_REG15(cpu, RM); - unsigned int rs = CHECK_READ_REG15(cpu, RS); - //if (RM == 15) rm += 8; - //if (RS == 15) rs += 8; - if (BITS(rs, 0, 7) == 0) { - shifter_operand = rm; - cpu->shifter_carry_out = cpu->CFlag; - } else if (BITS(rs, 0, 7) < 32) { - shifter_operand = rm << BITS(rs, 0, 7); - cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7)); - } else if (BITS(rs, 0, 7) == 32) { - shifter_operand = 0; - cpu->shifter_carry_out = BIT(rm, 0); - } else { - shifter_operand = 0; - cpu->shifter_carry_out = 0; - } - return shifter_operand; -} - -unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - //unsigned int rm = cpu->Reg[RM]; - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RM == 15) rm += 8; - unsigned int shifter_operand; - int shift_imm = BITS(sht_oper, 7, 11); - if (shift_imm == 0) { - shifter_operand = 0; - cpu->shifter_carry_out = BIT(rm, 31); - } else { - shifter_operand = rm >> shift_imm; - cpu->shifter_carry_out = BIT(rm, shift_imm - 1); - } - return shifter_operand; -} - -unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - unsigned int rs = CHECK_READ_REG15(cpu, RS); - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RS == 15) rs += 8; - //if (RM == 15) rm += 8; - unsigned int shifter_operand; - if (BITS(rs, 0, 7) == 0) { - shifter_operand = rm; - cpu->shifter_carry_out = cpu->CFlag; - } else if (BITS(rs, 0, 7) < 32) { - shifter_operand = rm >> BITS(rs, 0, 7); - cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); - } else if (BITS(rs, 0, 7) == 32) { - shifter_operand = 0; - cpu->shifter_carry_out = BIT(rm, 31); - } else { - shifter_operand = 0; - cpu->shifter_carry_out = 0; - } - return shifter_operand; -} - -unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - //unsigned int rm = cpu->Reg[RM]; - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RM == 15) rm += 8; - unsigned int shifter_operand; - int shift_imm = BITS(sht_oper, 7, 11); - if (shift_imm == 0) { - if (BIT(rm, 31)) { - shifter_operand = 0; - cpu->shifter_carry_out = BIT(rm, 31); - } else { - shifter_operand = 0xFFFFFFFF; - cpu->shifter_carry_out = BIT(rm, 31); - } - } else { - shifter_operand = static_cast<int>(rm) >> shift_imm; - cpu->shifter_carry_out = BIT(rm, shift_imm - 1); - } - return shifter_operand; -} - -unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - //unsigned int rs = cpu->Reg[RS]; - unsigned int rs = CHECK_READ_REG15(cpu, RS); - //unsigned int rm = cpu->Reg[RM]; - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RS == 15) rs += 8; - //if (RM == 15) rm += 8; - unsigned int shifter_operand; - if (BITS(rs, 0, 7) == 0) { - shifter_operand = rm; - cpu->shifter_carry_out = cpu->CFlag; - } else if (BITS(rs, 0, 7) < 32) { - shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7); - cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); - } else { - if (BIT(rm, 31) == 0) { - shifter_operand = 0; - } else - shifter_operand = 0xffffffff; - cpu->shifter_carry_out = BIT(rm, 31); - } - return shifter_operand; -} - -unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - unsigned int shifter_operand; - //unsigned int rm = cpu->Reg[RM]; - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RM == 15) rm += 8; - int shift_imm = BITS(sht_oper, 7, 11); - if (shift_imm == 0) { - shifter_operand = (cpu->CFlag << 31) | - (rm >> 1); - cpu->shifter_carry_out = BIT(rm, 0); - } else { - shifter_operand = ROTATE_RIGHT_32(rm, shift_imm); - cpu->shifter_carry_out = BIT(rm, shift_imm - 1); - } - return shifter_operand; -} - -unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) -{ -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - unsigned int rm = CHECK_READ_REG15(cpu, RM); - //if (RM == 15) rm += 8; - unsigned int rs = CHECK_READ_REG15(cpu, RS); - //if (RS == 15) rs += 8; - unsigned int shifter_operand; - if (BITS(rs, 0, 7) == 0) { - shifter_operand = rm; - cpu->shifter_carry_out = cpu->CFlag; - } else if (BITS(rs, 0, 4) == 0) { - shifter_operand = rm; - cpu->shifter_carry_out = BIT(rm, 31); - } else { - shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4)); - cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1); - } - #if 0 - if (cpu->icounter >= 20371544) { - DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS); - DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]); - } - #endif - return shifter_operand; -} - -//typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu); typedef struct _MiscImmeData { - unsigned int U; - unsigned int Rn; - unsigned int offset_8; + unsigned int U; + unsigned int Rn; + unsigned int offset_8; } MiscLSData; typedef struct _MiscRegData { - unsigned int U; - unsigned int Rn; - unsigned int Rm; + unsigned int U; + unsigned int Rn; + unsigned int Rm; } MiscRegData; typedef struct _MiscImmePreIdx { - unsigned int offset_8; - unsigned int U; - unsigned int Rn; + unsigned int offset_8; + unsigned int U; + unsigned int Rn; } MiscImmePreIdx; typedef struct _MiscRegPreIdx { - unsigned int U; - unsigned int Rn; - unsigned int Rm; + unsigned int U; + unsigned int Rn; + unsigned int Rm; } MiscRegPreIdx; typedef struct _MiscImmePstIdx { - unsigned int offset_8; - unsigned int U; - unsigned int Rn; + unsigned int offset_8; + unsigned int U; + unsigned int Rn; } MIscImmePstIdx; typedef struct _MiscRegPstIdx { - unsigned int Rn; - unsigned int Rm; - unsigned int U; + unsigned int Rn; + unsigned int Rm; + unsigned int U; } MiscRegPstIdx; typedef struct _LSWordorUnsignedByte { @@ -394,40 +285,38 @@ typedef struct _LSWordorUnsignedByte { #if USER_MODE_OPT static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ - switch(size) { - case 8: + switch(size) { + case 8: value = Memory::Read8(virt_addr); - break; - case 16: + break; + case 16: value = Memory::Read16(virt_addr); - break; - case 32: + break; + case 32: value = Memory::Read32(virt_addr); - break; - } - return NO_FAULT; + break; + } + return NO_FAULT; } -//static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size) -static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) -{ - switch(size) { - case 8: +static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) { + switch(size) { + case 8: Memory::Write8(virt_addr, value & 0xff); - break; - case 16: - Memory::Write16(virt_addr, value & 0xffff); - break; - case 32: - Memory::Write32(virt_addr, value); - break; - } - return NO_FAULT; + break; + case 16: + Memory::Write16(virt_addr, value & 0xffff); + break; + case 32: + Memory::Write32(virt_addr, value); + break; + } + return NO_FAULT; } -static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){ - *phys_addr = virt_addr; - return NO_FAULT; +static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw) { + *phys_addr = virt_addr; + return NO_FAULT; } #else @@ -440,738 +329,679 @@ fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_ typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); typedef struct _ldst_inst { - unsigned int inst; - get_addr_fp_t get_addr; + unsigned int inst; + get_addr_fp_t get_addr; } ldst_inst; -#define DEBUG_MSG DEBUG_LOG(ARM11, "in %s %d\n", __FUNCTION__, __LINE__); \ - DEBUG_LOG(ARM11, "inst is %x\n", inst); \ - CITRA_IGNORE_EXIT(0) +#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0) int CondPassed(arm_processor *cpu, unsigned int cond); -#define LnSWoUB(s) glue(LnSWoUB, s) -#define MLnS(s) glue(MLnS, s) -#define LdnStM(s) glue(LdnStM, s) - -#define W_BIT BIT(inst, 21) -#define U_BIT BIT(inst, 23) -#define I_BIT BIT(inst, 25) -#define P_BIT BIT(inst, 24) -#define OFFSET_12 BITS(inst, 0, 11) -fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - unsigned int Rn = BITS(inst, 16, 19); - unsigned int addr; - fault_t fault; - if (U_BIT) { - addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; - } else { - addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; - } - //if (Rn == 15) rn += 8; - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - return fault; -// return addr; -} - -fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rm == 15) rm += 8; - unsigned int addr; - if (U_BIT) { - addr = rn + rm; - } else { - addr = rn - rm; - } - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - return fault; -} - -fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) addr += 8; +#define LnSWoUB(s) glue(LnSWoUB, s) +#define MLnS(s) glue(MLnS, s) +#define LdnStM(s) glue(LdnStM, s) + +#define W_BIT BIT(inst, 21) +#define U_BIT BIT(inst, 23) +#define I_BIT BIT(inst, 25) +#define P_BIT BIT(inst, 24) +#define OFFSET_12 BITS(inst, 0, 11) +fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + unsigned int Rn = BITS(inst, 16, 19); + unsigned int addr; + fault_t fault; + if (U_BIT) { + addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; + } else { + addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; + } + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + return fault; +} + +fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int addr; + if (U_BIT) { + addr = rn + rm; + } else { + addr = rn - rm; + } + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + return fault; +} + +fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; + + if (U_BIT) { + cpu->Reg[Rn] += OFFSET_12; + } else { + cpu->Reg[Rn] -= OFFSET_12; + } + return fault; +} - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; +fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int addr; + if (U_BIT) { + addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; + } else { + addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; + } + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; - if (U_BIT) { - cpu->Reg[Rn] += OFFSET_12; - } else { - cpu->Reg[Rn] -= OFFSET_12; - } - return fault; + if (CondPassed(cpu, BITS(inst, 28, 31))) { + cpu->Reg[Rn] = addr; + } + return fault; +} + +fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int addr; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + + if (U_BIT) { + addr = rn + rm; + } else + addr = rn - rm; + if(BIT(inst, 20)){ // L BIT + } + if(BIT(inst, 6)){ // Sign Bit + } + if(BIT(inst, 5)){ // Half Bit + } + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31))) { + cpu->Reg[Rn] = addr; + } + return fault; +} + +fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int addr; + if (U_BIT) { + addr = rn + rm; + } else { + addr = rn - rm; + } + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if(fault) + return fault; + if (CondPassed(cpu, BITS(inst, 28, 31))) { + cpu->Reg[Rn] = addr; + } + return fault; +} +fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int shift = BITS(inst, 5, 6); + unsigned int shift_imm = BITS(inst, 7, 11); + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int index; + unsigned int addr; + + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + + switch (shift) { + case 0: + index = rm << shift_imm; + break; + case 1: + if (shift_imm == 0) { + index = 0; + } else { + index = rm >> shift_imm; + } + break; + case 2: + DEBUG_MSG; + break; + case 3: + DEBUG_MSG; + break; + } + if (U_BIT) { + addr = rn + index; + } else + addr = rn - index; + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if(fault) + return fault; + if (CondPassed(cpu, BITS(inst, 28, 31))) { + cpu->Reg[Rn] = addr; + } + + return fault; +} + +fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int shift = BITS(inst, 5, 6); + unsigned int shift_imm = BITS(inst, 7, 11); + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int index; + unsigned int addr; + + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + addr = rn; + switch (shift) { + case 0: + index = rm << shift_imm; + break; + case 1: + if (shift_imm == 0) { + index = 0; + } else { + index = rm >> shift_imm; + } + break; + case 2: + DEBUG_MSG; + break; + case 3: + DEBUG_MSG; + break; + } + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if(fault) + return fault; + if (CondPassed(cpu, BITS(inst, 28, 31))) { + if (U_BIT) + cpu->Reg[Rn] += index; + else + cpu->Reg[Rn] -= index; + } + + return fault; } -fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int addr; - if (U_BIT) { - addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; - } else { - addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; - } - #if 0 - if (Rn == 15) { - addr += 8; - } - #endif - - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31))) { - cpu->Reg[Rn] = addr; - } - return fault; -} - -fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int addr; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rn == 15) rn += 8; - //if (Rm == 15) rm += 8; - if (U_BIT) { - addr = rn + rm; - } else - addr = rn - rm; - if(BIT(inst, 20)){ /* L BIT */ - } - if(BIT(inst, 6)){ /* Sign Bit */ - } - if(BIT(inst, 5)){ /* Half Bit */ - } - - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31))) { - cpu->Reg[Rn] = addr; - } - return fault; -} - -fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rm == 15) rm += 8; - unsigned int addr; - if (U_BIT) { - addr = rn + rm; - } else { - addr = rn - rm; - } - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if(fault) - return fault; - if (CondPassed(cpu, BITS(inst, 28, 31))) { - cpu->Reg[Rn] = addr; - } - return fault; -} -fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int shift = BITS(inst, 5, 6); - unsigned int shift_imm = BITS(inst, 7, 11); - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int index; - unsigned int addr; - - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rm == 15) rm += 8; - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - switch (shift) { - case 0: - //DEBUG_MSG; - index = rm << shift_imm; - break; - case 1: -// DEBUG_MSG; - if (shift_imm == 0) { - index = 0; - } else { - index = rm >> shift_imm; - } - break; - case 2: - DEBUG_MSG; - break; - case 3: - DEBUG_MSG; - break; - } - if (U_BIT) { - addr = rn + index; - } else - addr = rn - index; - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if(fault) - return fault; - if (CondPassed(cpu, BITS(inst, 28, 31))) { - cpu->Reg[Rn] = addr; - } - - return fault; -} - -fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int shift = BITS(inst, 5, 6); - unsigned int shift_imm = BITS(inst, 7, 11); - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int index; - unsigned int addr; - - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rm == 15) rm += 8; - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - addr = rn; - switch (shift) { - case 0: - //DEBUG_MSG; - index = rm << shift_imm; - break; - case 1: -// DEBUG_MSG; - if (shift_imm == 0) { - index = 0; - } else { - index = rm >> shift_imm; - } - break; - case 2: - DEBUG_MSG; - break; - case 3: - DEBUG_MSG; - break; - } - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if(fault) - return fault; - if (CondPassed(cpu, BITS(inst, 28, 31))) { - if (U_BIT) - cpu->Reg[Rn] += index; - else - cpu->Reg[Rn] -= index; - } - - return fault; -} - -fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - - unsigned int addr = rn; - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31))) { - if (U_BIT) { - cpu->Reg[Rn] += rm; - } else { - cpu->Reg[Rn] -= rm; - } - } - return fault; -} - -fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int immedL = BITS(inst, 0, 3); - unsigned int immedH = BITS(inst, 8, 11); - - unsigned int Rn = BITS(inst, 16, 19); - unsigned int addr; - - unsigned int offset_8 = (immedH << 4) | immedL; - if (U_BIT) { - addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; - } else - addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; - #if 0 - if (Rn == 15) { - addr += 8; - } - #endif - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - return fault; -} - -fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int addr; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rn == 15) rn += 8; - //if (Rm == 15) rm += 8; - if (U_BIT) { - addr = rn + rm; - } else - addr = rn - rm; - if(BIT(inst, 20)){ /* L BIT */ - } - if(BIT(inst, 6)){ /* Sign Bit */ - } - if(BIT(inst, 5)){ /* Half Bit */ - } - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - return fault; -} - -fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int immedH = BITS(inst, 8, 11); - unsigned int immedL = BITS(inst, 0, 3); - unsigned int addr; - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - -// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); - unsigned int offset_8 = (immedH << 4) | immedL; - if (U_BIT) { - addr = rn + offset_8; - } else - addr = rn - offset_8; - - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31))) { - cpu->Reg[Rn] = addr; - } - return fault; -} - -fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int immedH = BITS(inst, 8, 11); - unsigned int immedL = BITS(inst, 0, 3); - unsigned int addr; - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - addr = rn; - - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31))) { - unsigned int offset_8 = (immedH << 4) | immedL; - if (U_BIT) { - rn += offset_8; - } else { - rn -= offset_8; - } - cpu->Reg[Rn] = rn; - } - - return fault; -} -fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - - unsigned int addr = rn; - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31))) { - if (U_BIT) { - cpu->Reg[Rn] += rm; - } else { - cpu->Reg[Rn] -= rm; - } - } - return fault; -} - -fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int i = BITS(inst, 0, 15); - int count = 0; - while(i) { - if(i & 1) count ++; - i = i >> 1; - } - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - unsigned int start_addr = rn - count * 4; - unsigned int end_addr = rn - 4; - - fault = check_address_validity(cpu, end_addr, &phys_addr, rw); - virt_addr = end_addr; - if (fault) return fault; - - fault = check_address_validity(cpu, start_addr, &phys_addr, rw); - virt_addr = start_addr; - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { - cpu->Reg[Rn] -= count * 4; - } - - return fault; -} - -fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int i = BITS(inst, 0, 15); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - int count = 0; - while(i) { - if(i & 1) count ++; - i = i >> 1; - } - - unsigned int start_addr = rn + 4; - unsigned int end_addr = rn + count * 4; - - fault = check_address_validity(cpu, end_addr, &phys_addr, rw); - virt_addr = end_addr; - if (fault) return fault; - - fault = check_address_validity(cpu, start_addr, &phys_addr, rw); - virt_addr = start_addr; - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { - cpu->Reg[Rn] += count * 4; - } - return fault; -} - -fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int i = BITS(inst, 0, 15); - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - int count = 0; - while(i) { - if(i & 1) count ++; - i = i >> 1; - } - //if (Rn == 15) rn += 8; - unsigned int start_addr = rn; - unsigned int end_addr = rn + count * 4 - 4; - - fault = check_address_validity(cpu, end_addr, &phys_addr, rw); - virt_addr = end_addr; - if (fault) return fault; - - fault = check_address_validity(cpu, start_addr, &phys_addr, rw); - virt_addr = start_addr; - if (fault) return fault; - - if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { - cpu->Reg[Rn] += count * 4; - } - return fault; -} - -fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int i = BITS(inst, 0, 15); - int count = 0; - while(i) { - if(i & 1) count ++; - i = i >> 1; - } - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - unsigned int start_addr = rn - count * 4 + 4; - unsigned int end_addr = rn; - - fault = check_address_validity(cpu, end_addr, &phys_addr, rw); - virt_addr = end_addr; - if (fault) return fault; - - fault = check_address_validity(cpu, start_addr, &phys_addr, rw); - if (fault) return fault; - virt_addr = start_addr; - - if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { - cpu->Reg[Rn] -= count * 4; - } - return fault; -} - -fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) -{ - fault_t fault; - unsigned int shift = BITS(inst, 5, 6); - unsigned int shift_imm = BITS(inst, 7, 11); - unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); - unsigned int index; - unsigned int addr; - - unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); - //if (Rm == 15) rm += 8; - unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); - //if (Rn == 15) rn += 8; - switch (shift) { - case 0: - //DEBUG_MSG; - index = rm << shift_imm; - break; - case 1: -// DEBUG_MSG; - if (shift_imm == 0) { - index = 0; - } else { - index = rm >> shift_imm; - } - break; - case 2: - if (shift_imm == 0){ /* ASR #32 */ - if (rm >> 31) - index = 0xFFFFFFFF; - else - index = 0; - } - else { - index = static_cast<int>(rm) >> shift_imm; - } - break; - case 3: - DEBUG_MSG; - break; - } - if (U_BIT) { - addr = rn + index; - } else - addr = rn - index; - virt_addr = addr; - fault = check_address_validity(cpu, addr, &phys_addr, rw); - return fault; -} - -#define ISNEG(n) (n < 0) -#define ISPOS(n) (n >= 0) - -//enum { -// COND = (1 << 0), -// NON_BRANCH = (1 << 1), -// DIRECT_BRANCH = (1 << 2), -// INDIRECT_BRANCH = (1 << 3), -// CALL = (1 << 4), -// RET = (1 << 5), -// END_OF_PAGE = (1 << 6), -// THUMB = (1 << 7) -//}; +fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + + unsigned int addr = rn; + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31))) { + if (U_BIT) { + cpu->Reg[Rn] += rm; + } else { + cpu->Reg[Rn] -= rm; + } + } + return fault; +} + +fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int immedL = BITS(inst, 0, 3); + unsigned int immedH = BITS(inst, 8, 11); + + unsigned int Rn = BITS(inst, 16, 19); + unsigned int addr; + + unsigned int offset_8 = (immedH << 4) | immedL; + if (U_BIT) { + addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; + } else + addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + return fault; +} + +fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int addr; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + if (U_BIT) { + addr = rn + rm; + } else + addr = rn - rm; + if(BIT(inst, 20)){ // L BIT + } + if(BIT(inst, 6)){ // Sign Bit + } + if(BIT(inst, 5)){ // Half Bit + } + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + return fault; +} + +fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int immedH = BITS(inst, 8, 11); + unsigned int immedL = BITS(inst, 0, 3); + unsigned int addr; + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int offset_8 = (immedH << 4) | immedL; + + if (U_BIT) { + addr = rn + offset_8; + } else + addr = rn - offset_8; + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31))) { + cpu->Reg[Rn] = addr; + } + return fault; +} + +fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int immedH = BITS(inst, 8, 11); + unsigned int immedL = BITS(inst, 0, 3); + unsigned int addr; + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + addr = rn; + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31))) { + unsigned int offset_8 = (immedH << 4) | immedL; + if (U_BIT) { + rn += offset_8; + } else { + rn -= offset_8; + } + cpu->Reg[Rn] = rn; + } + + return fault; +} +fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int addr = rn; + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31))) { + if (U_BIT) { + cpu->Reg[Rn] += rm; + } else { + cpu->Reg[Rn] -= rm; + } + } + return fault; +} + +fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int i = BITS(inst, 0, 15); + int count = 0; + while(i) { + if(i & 1) count ++; + i = i >> 1; + } + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int start_addr = rn - count * 4; + unsigned int end_addr = rn - 4; + + fault = check_address_validity(cpu, end_addr, &phys_addr, rw); + virt_addr = end_addr; + if (fault) return fault; + + fault = check_address_validity(cpu, start_addr, &phys_addr, rw); + virt_addr = start_addr; + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { + cpu->Reg[Rn] -= count * 4; + } + + return fault; +} + +fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int i = BITS(inst, 0, 15); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + int count = 0; + while(i) { + if(i & 1) count ++; + i = i >> 1; + } + + unsigned int start_addr = rn + 4; + unsigned int end_addr = rn + count * 4; + + fault = check_address_validity(cpu, end_addr, &phys_addr, rw); + virt_addr = end_addr; + if (fault) return fault; + + fault = check_address_validity(cpu, start_addr, &phys_addr, rw); + virt_addr = start_addr; + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { + cpu->Reg[Rn] += count * 4; + } + return fault; +} + +fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int i = BITS(inst, 0, 15); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + int count = 0; + while(i) { + if(i & 1) count ++; + i = i >> 1; + } + unsigned int start_addr = rn; + unsigned int end_addr = rn + count * 4 - 4; + + fault = check_address_validity(cpu, end_addr, &phys_addr, rw); + virt_addr = end_addr; + if (fault) return fault; + + fault = check_address_validity(cpu, start_addr, &phys_addr, rw); + virt_addr = start_addr; + if (fault) return fault; + + if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { + cpu->Reg[Rn] += count * 4; + } + return fault; +} + +fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int i = BITS(inst, 0, 15); + int count = 0; + while(i) { + if(i & 1) count ++; + i = i >> 1; + } + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + unsigned int start_addr = rn - count * 4 + 4; + unsigned int end_addr = rn; + + fault = check_address_validity(cpu, end_addr, &phys_addr, rw); + virt_addr = end_addr; + if (fault) return fault; + + fault = check_address_validity(cpu, start_addr, &phys_addr, rw); + if (fault) return fault; + virt_addr = start_addr; + + if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { + cpu->Reg[Rn] -= count * 4; + } + return fault; +} + +fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { + fault_t fault; + unsigned int shift = BITS(inst, 5, 6); + unsigned int shift_imm = BITS(inst, 7, 11); + unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rm = BITS(inst, 0, 3); + unsigned int index; + unsigned int addr; + + unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); + unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); + switch (shift) { + case 0: + index = rm << shift_imm; + break; + case 1: + if (shift_imm == 0) { + index = 0; + } else { + index = rm >> shift_imm; + } + break; + case 2: + if (shift_imm == 0){ // ASR #32 + if (rm >> 31) + index = 0xFFFFFFFF; + else + index = 0; + } + else { + index = static_cast<int>(rm) >> shift_imm; + } + break; + case 3: + DEBUG_MSG; + break; + } + if (U_BIT) { + addr = rn + index; + } else + addr = rn - index; + + virt_addr = addr; + fault = check_address_validity(cpu, addr, &phys_addr, rw); + + return fault; +} + +#define ISNEG(n) (n < 0) +#define ISPOS(n) (n >= 0) typedef struct _arm_inst { - unsigned int idx; - unsigned int cond; - int br; - int load_r15; - char component[0]; + unsigned int idx; + unsigned int cond; + int br; + int load_r15; + char component[0]; } arm_inst; +typedef struct generic_arm_inst { + u32 Ra; + u32 Rm; + u32 Rn; + u32 Rd; + u8 op1; + u8 op2; +} generic_arm_inst; + typedef struct _adc_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } adc_inst; typedef struct _add_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } add_inst; typedef struct _orr_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } orr_inst; typedef struct _and_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } and_inst; typedef struct _eor_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } eor_inst; typedef struct _bbl_inst { - unsigned int L; - int signed_immed_24; - unsigned int next_addr; - unsigned int jmp_addr; + unsigned int L; + int signed_immed_24; + unsigned int next_addr; + unsigned int jmp_addr; } bbl_inst; typedef struct _bx_inst { - unsigned int Rm; + unsigned int Rm; } bx_inst; typedef struct _blx_inst { - union { - int32_t signed_immed_24; - uint32_t Rm; - } val; - unsigned int inst; + union { + int32_t signed_immed_24; + uint32_t Rm; + } val; + unsigned int inst; } blx_inst; typedef struct _clz_inst { - unsigned int Rm; - unsigned int Rd; + unsigned int Rm; + unsigned int Rd; } clz_inst; typedef struct _cps_inst { - unsigned int imod0; - unsigned int imod1; - unsigned int mmod; - unsigned int A, I, F; - unsigned int mode; + unsigned int imod0; + unsigned int imod1; + unsigned int mmod; + unsigned int A, I, F; + unsigned int mode; } cps_inst; typedef struct _clrex_inst { } clrex_inst; typedef struct _cpy_inst { - unsigned int Rm; - unsigned int Rd; + unsigned int Rm; + unsigned int Rd; } cpy_inst; typedef struct _bic_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } bic_inst; typedef struct _sub_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } sub_inst; typedef struct _tst_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } tst_inst; typedef struct _cmn_inst { - unsigned int I; - //unsigned int S; - unsigned int Rn; - //unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int Rn; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } cmn_inst; typedef struct _teq_inst { - unsigned int I; - unsigned int Rn; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int Rn; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } teq_inst; typedef struct _stm_inst { - unsigned int inst; + unsigned int inst; } stm_inst; struct bkpt_inst { }; struct blx1_inst { - unsigned int addr; + unsigned int addr; }; struct blx2_inst { - unsigned int Rm; + unsigned int Rm; }; typedef struct _stc_inst { @@ -1181,1965 +1011,2188 @@ typedef struct _ldc_inst { } ldc_inst; typedef struct _swi_inst { - unsigned int num; + unsigned int num; } swi_inst; typedef struct _cmp_inst { - unsigned int I; - unsigned int Rn; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int Rn; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } cmp_inst; typedef struct _mov_inst { - unsigned int I; - unsigned int S; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } mov_inst; typedef struct _mvn_inst { - unsigned int I; - unsigned int S; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } mvn_inst; typedef struct _rev_inst { - unsigned int Rd; - unsigned int Rm; + unsigned int Rd; + unsigned int Rm; } rev_inst; typedef struct _rsb_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } rsb_inst; typedef struct _rsc_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } rsc_inst; typedef struct _sbc_inst { - unsigned int I; - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int shifter_operand; - shtop_fp_t shtop_func; + unsigned int I; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int shifter_operand; + shtop_fp_t shtop_func; } sbc_inst; typedef struct _mul_inst { - unsigned int S; - unsigned int Rd; - unsigned int Rs; - unsigned int Rm; + unsigned int S; + unsigned int Rd; + unsigned int Rs; + unsigned int Rm; } mul_inst; typedef struct _smul_inst { - unsigned int Rd; - unsigned int Rs; - unsigned int Rm; - unsigned int x; - unsigned int y; + unsigned int Rd; + unsigned int Rs; + unsigned int Rm; + unsigned int x; + unsigned int y; } smul_inst; typedef struct _umull_inst { - unsigned int S; - unsigned int RdHi; - unsigned int RdLo; - unsigned int Rs; - unsigned int Rm; + unsigned int S; + unsigned int RdHi; + unsigned int RdLo; + unsigned int Rs; + unsigned int Rm; } umull_inst; typedef struct _smlad_inst { - unsigned int m; - unsigned int Rm; - unsigned int Rd; - unsigned int Ra; - unsigned int Rn; + unsigned int m; + unsigned int Rm; + unsigned int Rd; + unsigned int Ra; + unsigned int Rn; } smlad_inst; typedef struct _smla_inst { - unsigned int x; - unsigned int y; - unsigned int Rm; - unsigned int Rd; - unsigned int Rs; - unsigned int Rn; + unsigned int x; + unsigned int y; + unsigned int Rm; + unsigned int Rd; + unsigned int Rs; + unsigned int Rn; } smla_inst; +typedef struct ssat_inst { + unsigned int Rn; + unsigned int Rd; + unsigned int imm5; + unsigned int sat_imm; + unsigned int shift_type; +} ssat_inst; + +typedef struct umaal_inst { + unsigned int Rn; + unsigned int Rm; + unsigned int RdHi; + unsigned int RdLo; +} umaal_inst; + typedef struct _umlal_inst { - unsigned int S; - unsigned int Rm; - unsigned int Rs; - unsigned int RdHi; - unsigned int RdLo; + unsigned int S; + unsigned int Rm; + unsigned int Rs; + unsigned int RdHi; + unsigned int RdLo; } umlal_inst; typedef struct _smlal_inst { - unsigned int S; - unsigned int Rm; - unsigned int Rs; - unsigned int RdHi; - unsigned int RdLo; + unsigned int S; + unsigned int Rm; + unsigned int Rs; + unsigned int RdHi; + unsigned int RdLo; } smlal_inst; typedef struct _mla_inst { - unsigned int S; - unsigned int Rn; - unsigned int Rd; - unsigned int Rs; - unsigned int Rm; + unsigned int S; + unsigned int Rn; + unsigned int Rd; + unsigned int Rs; + unsigned int Rm; } mla_inst; typedef struct _mrc_inst { - unsigned int opcode_1; - unsigned int opcode_2; - unsigned int cp_num; - unsigned int crn; - unsigned int crm; - unsigned int Rd; - unsigned int inst; + unsigned int opcode_1; + unsigned int opcode_2; + unsigned int cp_num; + unsigned int crn; + unsigned int crm; + unsigned int Rd; + unsigned int inst; } mrc_inst; typedef struct _mcr_inst { - unsigned int opcode_1; - unsigned int opcode_2; - unsigned int cp_num; - unsigned int crn; - unsigned int crm; - unsigned int Rd; - unsigned int inst; + unsigned int opcode_1; + unsigned int opcode_2; + unsigned int cp_num; + unsigned int crn; + unsigned int crm; + unsigned int Rd; + unsigned int inst; } mcr_inst; typedef struct _mrs_inst { - unsigned int R; - unsigned int Rd; + unsigned int R; + unsigned int Rd; } mrs_inst; typedef struct _msr_inst { - unsigned int field_mask; - unsigned int R; - unsigned int inst; + unsigned int field_mask; + unsigned int R; + unsigned int inst; } msr_inst; typedef struct _pld_inst { } pld_inst; typedef struct _sxtb_inst { - unsigned int Rd; - unsigned int Rm; - unsigned int rotate; + unsigned int Rd; + unsigned int Rm; + unsigned int rotate; } sxtb_inst; typedef struct _sxtab_inst { - unsigned int Rd; - unsigned int Rn; - unsigned int Rm; - unsigned rotate; + unsigned int Rd; + unsigned int Rn; + unsigned int Rm; + unsigned rotate; } sxtab_inst; typedef struct _sxtah_inst { - unsigned int Rd; - unsigned int Rn; - unsigned int Rm; - unsigned int rotate; + unsigned int Rd; + unsigned int Rn; + unsigned int Rm; + unsigned int rotate; } sxtah_inst; typedef struct _sxth_inst { - unsigned int Rd; - unsigned int Rm; - unsigned int rotate; + unsigned int Rd; + unsigned int Rm; + unsigned int rotate; } sxth_inst; typedef struct _uxtab_inst { - unsigned int Rn; - unsigned int Rd; - unsigned int rotate; - unsigned int Rm; + unsigned int Rn; + unsigned int Rd; + unsigned int rotate; + unsigned int Rm; } uxtab_inst; typedef struct _uxtah_inst { - unsigned int Rn; - unsigned int Rd; - unsigned int rotate; - unsigned int Rm; + unsigned int Rn; + unsigned int Rd; + unsigned int rotate; + unsigned int Rm; } uxtah_inst; typedef struct _uxth_inst { - unsigned int Rd; - unsigned int Rm; - unsigned int rotate; + unsigned int Rd; + unsigned int Rm; + unsigned int rotate; } uxth_inst; typedef struct _cdp_inst { - unsigned int opcode_1; - unsigned int CRn; - unsigned int CRd; - unsigned int cp_num; - unsigned int opcode_2; - unsigned int CRm; - uint32 inst; + unsigned int opcode_1; + unsigned int CRn; + unsigned int CRd; + unsigned int cp_num; + unsigned int opcode_2; + unsigned int CRm; + uint32 inst; }cdp_inst; typedef struct _uxtb_inst { - unsigned int Rd; - unsigned int Rm; - unsigned int rotate; + unsigned int Rd; + unsigned int Rm; + unsigned int rotate; } uxtb_inst; typedef struct _swp_inst { - unsigned int Rn; - unsigned int Rd; - unsigned int Rm; + unsigned int Rn; + unsigned int Rd; + unsigned int Rm; } swp_inst; typedef struct _b_2_thumb { - unsigned int imm; + unsigned int imm; }b_2_thumb; typedef struct _b_cond_thumb { - unsigned int imm; - unsigned int cond; + unsigned int imm; + unsigned int cond; }b_cond_thumb; typedef struct _bl_1_thumb { - unsigned int imm; + unsigned int imm; }bl_1_thumb; typedef struct _bl_2_thumb { - unsigned int imm; + unsigned int imm; }bl_2_thumb; typedef struct _blx_1_thumb { - unsigned int imm; - unsigned int instr; + unsigned int imm; + unsigned int instr; }blx_1_thumb; +typedef struct _pkh_inst { + u32 Rm; + u32 Rn; + u32 Rd; + u8 imm; +} pkh_inst; + typedef arm_inst * ARM_INST_PTR; -#define CACHE_BUFFER_SIZE (64 * 1024 * 2000) +#define CACHE_BUFFER_SIZE (64 * 1024 * 2000) char inst_buf[CACHE_BUFFER_SIZE]; int top = 0; -inline void *AllocBuffer(unsigned int size) -{ - int start = top; - top += size; - if (top > CACHE_BUFFER_SIZE) { - DEBUG_LOG(ARM11, "inst_buf is full\n"); - CITRA_IGNORE_EXIT(-1); - } - return (void *)&inst_buf[start]; -} - -int CondPassed(arm_processor *cpu, unsigned int cond) -{ - #define NFLAG cpu->NFlag - #define ZFLAG cpu->ZFlag - #define CFLAG cpu->CFlag - #define VFLAG cpu->VFlag - int temp; - switch (cond) { - case 0x0: - temp = ZFLAG; - break; - case 0x1: /* NE */ - temp = !ZFLAG; - break; - case 0x6: /* VS */ - temp = VFLAG; - break; - case 0x7: /* VC */ - temp = !VFLAG; - break; - case 0x4: /* MI */ - temp = NFLAG; - break; - case 0x5: /* PL */ - temp = !NFLAG; - break; - case 0x2: /* CS */ - temp = CFLAG; - break; - case 0x3: /* CC */ - temp = !CFLAG; - break; - case 0x8: /* HI */ - temp = (CFLAG && !ZFLAG); - break; - case 0x9: /* LS */ - temp = (!CFLAG || ZFLAG); - break; - case 0xa: /* GE */ - temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); - break; - case 0xb: /* LT */ - temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); - break; - case 0xc: /* GT */ - temp = ((!NFLAG && !VFLAG && !ZFLAG) - || (NFLAG && VFLAG && !ZFLAG)); - break; - case 0xd: /* LE */ - temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) - || ZFLAG; - break; - case 0xe: /* AL */ - temp = 1; - break; - case 0xf: -// DEBUG_LOG(ARM11, "inst is %x\n"); -// DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter); -// CITRA_IGNORE_EXIT(-1); - temp = 1; - break; - } - return temp; +inline void *AllocBuffer(unsigned int size) { + int start = top; + top += size; + if (top > CACHE_BUFFER_SIZE) { + LOG_ERROR(Core_ARM11, "inst_buf is full"); + CITRA_IGNORE_EXIT(-1); + } + return (void *)&inst_buf[start]; +} + +int CondPassed(arm_processor *cpu, unsigned int cond) { + #define NFLAG cpu->NFlag + #define ZFLAG cpu->ZFlag + #define CFLAG cpu->CFlag + #define VFLAG cpu->VFlag + + int temp; + + switch (cond) { + case 0x0: + temp = ZFLAG; + break; + case 0x1: // NE + temp = !ZFLAG; + break; + case 0x6: // VS + temp = VFLAG; + break; + case 0x7: // VC + temp = !VFLAG; + break; + case 0x4: // MI + temp = NFLAG; + break; + case 0x5: // PL + temp = !NFLAG; + break; + case 0x2: // CS + temp = CFLAG; + break; + case 0x3: // CC + temp = !CFLAG; + break; + case 0x8: // HI + temp = (CFLAG && !ZFLAG); + break; + case 0x9: // LS + temp = (!CFLAG || ZFLAG); + break; + case 0xa: // GE + temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); + break; + case 0xb: // LT + temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); + break; + case 0xc: // GT + temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); + break; + case 0xd: // LE + temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; + break; + case 0xe: // AL + temp = 1; + break; + case 0xf: + temp = 1; + break; + } + return temp; } enum DECODE_STATUS { - DECODE_SUCCESS, - DECODE_FAILURE + DECODE_SUCCESS, + DECODE_FAILURE }; int decode_arm_instr(uint32_t instr, int32_t *idx); -shtop_fp_t get_shtop(unsigned int inst) -{ - if (BIT(inst, 25)) { - return DPO(Immediate); - } else if (BITS(inst, 4, 11) == 0) { - return DPO(Register); - } else if (BITS(inst, 4, 6) == 0) { - return DPO(LogicalShiftLeftByImmediate); - } else if (BITS(inst, 4, 7) == 1) { - return DPO(LogicalShiftLeftByRegister); - } else if (BITS(inst, 4, 6) == 2) { - return DPO(LogicalShiftRightByImmediate); - } else if (BITS(inst, 4, 7) == 3) { - return DPO(LogicalShiftRightByRegister); - } else if (BITS(inst, 4, 6) == 4) { - return DPO(ArithmeticShiftRightByImmediate); - } else if (BITS(inst, 4, 7) == 5) { - return DPO(ArithmeticShiftRightByRegister); - } else if (BITS(inst, 4, 6) == 6) { - return DPO(RotateRightByImmediate); - } else if (BITS(inst, 4, 7) == 7) { - return DPO(RotateRightByRegister); - } - return NULL; -} - -get_addr_fp_t get_calc_addr_op(unsigned int inst) -{ - /* 1 */ - if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LnSWoUB(ImmediateOffset); - } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { -// DEBUG_MSG; -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LnSWoUB(RegisterOffset); - } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { -// DEBUG_MSG; -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LnSWoUB(ScaledRegisterOffset); - } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LnSWoUB(ImmediatePreIndexed); - } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { - return LnSWoUB(RegisterPreIndexed); - } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { - return LnSWoUB(ScaledRegisterPreIndexed); - } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { - return LnSWoUB(ImmediatePostIndexed); - } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { -// DEBUG_MSG; - return LnSWoUB(RegisterPostIndexed); - } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { - return LnSWoUB(ScaledRegisterPostIndexed); -// DEBUG_MSG; - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { - /* 2 */ -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return MLnS(ImmediateOffset); -// DEBUG_MSG; - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { -// DEBUG_LOG(ARM11, "line is %d\n", __LINE__); - return MLnS(RegisterOffset); -// DEBUG_MSG; - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { -// DEBUG_LOG(ARM11, "line is %d\n", __LINE__); - return MLnS(ImmediatePreIndexed); -// DEBUG_MSG; - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { - return MLnS(RegisterPreIndexed); - } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { -// DEBUG_MSG; - return MLnS(ImmediatePostIndexed); - } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { - //DEBUG_MSG; - return MLnS(RegisterPostIndexed); - } else if (BITS(inst, 23, 27) == 0x11) { - /* 3 */ -// DEBUG_MSG; -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LdnStM(IncrementAfter); - } else if (BITS(inst, 23, 27) == 0x13) { -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LdnStM(IncrementBefore); -// DEBUG_MSG; - } else if (BITS(inst, 23, 27) == 0x10) { -// DEBUG_MSG; -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LdnStM(DecrementAfter); - } else if (BITS(inst, 23, 27) == 0x12) { -// DEBUG_MSG; -// DEBUG_LOG(ARM11, "line is %d", __LINE__); - return LdnStM(DecrementBefore); - } - #if 0 - DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__); - DEBUG_LOG(ARM11, "inst:%x\n", inst); - CITRA_IGNORE_EXIT(-1); - #endif - return NULL; +shtop_fp_t get_shtop(unsigned int inst) { + if (BIT(inst, 25)) { + return DPO(Immediate); + } else if (BITS(inst, 4, 11) == 0) { + return DPO(Register); + } else if (BITS(inst, 4, 6) == 0) { + return DPO(LogicalShiftLeftByImmediate); + } else if (BITS(inst, 4, 7) == 1) { + return DPO(LogicalShiftLeftByRegister); + } else if (BITS(inst, 4, 6) == 2) { + return DPO(LogicalShiftRightByImmediate); + } else if (BITS(inst, 4, 7) == 3) { + return DPO(LogicalShiftRightByRegister); + } else if (BITS(inst, 4, 6) == 4) { + return DPO(ArithmeticShiftRightByImmediate); + } else if (BITS(inst, 4, 7) == 5) { + return DPO(ArithmeticShiftRightByRegister); + } else if (BITS(inst, 4, 6) == 6) { + return DPO(RotateRightByImmediate); + } else if (BITS(inst, 4, 7) == 7) { + return DPO(RotateRightByRegister); + } + return nullptr; +} + +get_addr_fp_t get_calc_addr_op(unsigned int inst) { + if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { + return LnSWoUB(ImmediateOffset); + } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { + return LnSWoUB(RegisterOffset); + } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { + return LnSWoUB(ScaledRegisterOffset); + } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { + return LnSWoUB(ImmediatePreIndexed); + } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { + return LnSWoUB(RegisterPreIndexed); + } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { + return LnSWoUB(ScaledRegisterPreIndexed); + } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { + return LnSWoUB(ImmediatePostIndexed); + } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { + return LnSWoUB(RegisterPostIndexed); + } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { + return LnSWoUB(ScaledRegisterPostIndexed); + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + return MLnS(ImmediateOffset); + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + return MLnS(RegisterOffset); + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + return MLnS(ImmediatePreIndexed); + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + return MLnS(RegisterPreIndexed); + } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + return MLnS(ImmediatePostIndexed); + } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + return MLnS(RegisterPostIndexed); + } else if (BITS(inst, 23, 27) == 0x11) { + return LdnStM(IncrementAfter); + } else if (BITS(inst, 23, 27) == 0x13) { + return LdnStM(IncrementBefore); + } else if (BITS(inst, 23, 27) == 0x10) { + return LdnStM(DecrementAfter); + } else if (BITS(inst, 23, 27) == 0x12) { + return LdnStM(DecrementBefore); + } + return nullptr; } #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) -#define CHECK_RN (inst_cream->Rn == 15) -#define CHECK_RM (inst_cream->Rm == 15) -#define CHECK_RS (inst_cream->Rs == 15) +#define CHECK_RN (inst_cream->Rn == 15) +#define CHECK_RM (inst_cream->Rm == 15) +#define CHECK_RS (inst_cream->Rs == 15) +#define UNIMPLEMENTED_INSTRUCTION(mnemonic) \ + LOG_ERROR(Core_ARM11, "unimplemented instruction: %s", mnemonic); \ + CITRA_IGNORE_EXIT(-1); \ + return nullptr; ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); - adc_inst *inst_cream = (adc_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); + adc_inst *inst_cream = (adc_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); - add_inst *inst_cream = (add_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); + add_inst *inst_cream = (add_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); - and_inst *inst_cream = (and_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) - inst_base->br = INDIRECT_BRANCH; - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); + and_inst *inst_cream = (and_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (inst_cream->Rd == 15) + inst_base->br = INDIRECT_BRANCH; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) { - #define POSBRANCH ((inst & 0x7fffff) << 2) - #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) + #define POSBRANCH ((inst & 0x7fffff) << 2) + #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); - bbl_inst *inst_cream = (bbl_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); + bbl_inst *inst_cream = (bbl_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; - if (BIT(inst, 24)) - inst_base->br = CALL; - if (BITS(inst, 28, 31) <= 0xe) - inst_base->br |= COND; + if (BIT(inst, 24)) + inst_base->br = CALL; + if (BITS(inst, 28, 31) <= 0xe) + inst_base->br |= COND; - inst_cream->L = BIT(inst, 24); - inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; + inst_cream->L = BIT(inst, 24); + inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); - bic_inst *inst_cream = (bic_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - - if (inst_cream->Rd == 15) - inst_base->br = INDIRECT_BRANCH; - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); + bic_inst *inst_cream = (bic_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + + if (inst_cream->Rd == 15) + inst_base->br = INDIRECT_BRANCH; + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BKPT"); } ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); - blx_inst *inst_cream = (blx_inst *)inst_base->component; - - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = INDIRECT_BRANCH; - - inst_cream->inst = inst; - if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { - inst_cream->val.Rm = BITS(inst, 0, 3); - } else { - inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); - //DEBUG_LOG(ARM11, " blx inst is %x\n", inst); - //CITRA_IGNORE_EXIT(-1); -// DEBUG_MSG; - } + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); + blx_inst *inst_cream = (blx_inst *)inst_base->component; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = INDIRECT_BRANCH; + + inst_cream->inst = inst; + if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { + inst_cream->val.Rm = BITS(inst, 0, 3); + } else { + inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); + } - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); - bx_inst *inst_cream = (bx_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); + bx_inst *inst_cream = (bx_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = INDIRECT_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = INDIRECT_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 0, 3); - return inst_base; + return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} +ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); - cdp_inst *inst_cream = (cdp_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->CRm = BITS(inst, 0, 3); - inst_cream->CRd = BITS(inst, 12, 15); - inst_cream->CRn = BITS(inst, 16, 19); - inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->opcode_2 = BITS(inst, 5, 7); - inst_cream->opcode_1 = BITS(inst, 20, 23); - inst_cream->inst = inst; - - DEBUG_LOG(ARM11, "in func %s inst %x index %x\n", __FUNCTION__, inst, index); - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); + cdp_inst *inst_cream = (cdp_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->CRm = BITS(inst, 0, 3); + inst_cream->CRd = BITS(inst, 12, 15); + inst_cream->CRn = BITS(inst, 16, 19); + inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->opcode_2 = BITS(inst, 5, 7); + inst_cream->opcode_1 = BITS(inst, 20, 23); + inst_cream->inst = inst; + + LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index); + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); - clz_inst *inst_cream = (clz_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); + clz_inst *inst_cream = (clz_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->Rm = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RM) - inst_base->load_r15 = 1; + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RM) + inst_base->load_r15 = 1; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); - cmn_inst *inst_cream = (cmn_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->I = BIT(inst, 25); - //inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - //inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); + cmn_inst *inst_cream = (cmn_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->I = BIT(inst, 25); + //inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + //inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); - cmp_inst *inst_cream = (cmp_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->I = BIT(inst, 25); - inst_cream->Rn = BITS(inst, 16, 19); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); + cmp_inst *inst_cream = (cmp_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->I = BIT(inst, 25); + inst_cream->Rn = BITS(inst, 16, 19); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); - cps_inst *inst_cream = (cps_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); + cps_inst *inst_cream = (cps_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_cream->imod0 = BIT(inst, 18); - inst_cream->imod1 = BIT(inst, 19); - inst_cream->mmod = BIT(inst, 17); - inst_cream->A = BIT(inst, 8); - inst_cream->I = BIT(inst, 7); - inst_cream->F = BIT(inst, 6); - inst_cream->mode = BITS(inst, 0, 4); + inst_cream->imod0 = BIT(inst, 18); + inst_cream->imod1 = BIT(inst, 19); + inst_cream->mmod = BIT(inst, 17); + inst_cream->A = BIT(inst, 8); + inst_cream->I = BIT(inst, 7); + inst_cream->F = BIT(inst, 6); + inst_cream->mode = BITS(inst, 0, 4); - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); - mov_inst *inst_cream = (mov_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); + mov_inst *inst_cream = (mov_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_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); - eor_inst *inst_cream = (eor_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - if (CHECK_RN) - inst_base->load_r15 = 1; - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); + eor_inst *inst_cream = (eor_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + if (CHECK_RN) + inst_base->load_r15 = 1; + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(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(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_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); + inst_cream->inst = inst; + inst_cream->get_addr = get_calc_addr_op(inst); - if (BIT(inst, 15)) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (BIT(inst, 15)) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); - sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); + sxtb_inst *inst_cream = (sxtb_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->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->rotate = BITS(inst, 10, 11); - if (CHECK_RM) - inst_base->load_r15 = 1; + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->rotate = BITS(inst, 10, 11); + if (CHECK_RM) + inst_base->load_r15 = 1; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(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(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_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->inst = inst; - inst_cream->get_addr = get_calc_addr_op(inst); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(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(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_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->inst = inst; - inst_cream->get_addr = get_calc_addr_op(inst); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); - uxth_inst *inst_cream = (uxth_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); + uxth_inst *inst_cream = (uxth_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->Rd = BITS(inst, 12, 15); - inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - if (CHECK_RM) - inst_base->load_r15 = 1; + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rm = BITS(inst, 0, 3); + if (CHECK_RM) + inst_base->load_r15 = 1; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); - uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); + uxtah_inst *inst_cream = (uxtah_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->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - if (CHECK_RM || CHECK_RN) - inst_base->load_r15 = 1; + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rm = BITS(inst, 0, 3); + if (CHECK_RM || CHECK_RN) + inst_base->load_r15 = 1; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(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; - if (I_BIT == 0) { - inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); - } else { - DEBUG_MSG; - } - #if 0 - inst_cream->get_addr = get_calc_addr_op(inst); - if(inst == 0x54f13001) { - DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); - } - #endif - - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + 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; + if (I_BIT == 0) { + inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else { + DEBUG_MSG; + } + #if 0 + inst_cream->get_addr = get_calc_addr_op(inst); + if(inst == 0x54f13001) { + DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); + } + #endif + + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(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(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_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); + inst_cream->inst = inst; + inst_cream->get_addr = get_calc_addr_op(inst); - return inst_base; + 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(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_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); + 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; + 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; + 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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(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; - if (I_BIT == 0) { - inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); - } else { - DEBUG_MSG; - } + 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; + if (I_BIT == 0) { + inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else { + DEBUG_MSG; + } - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); - mcr_inst *inst_cream = (mcr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - - inst_cream->crn = BITS(inst, 16, 19); - inst_cream->crm = BITS(inst, 0, 3); - inst_cream->opcode_1 = BITS(inst, 21, 23); - inst_cream->opcode_2 = BITS(inst, 5, 7); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->inst = inst; - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); + mcr_inst *inst_cream = (mcr_inst *)inst_base->component; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + + inst_cream->crn = BITS(inst, 16, 19); + inst_cream->crm = BITS(inst, 0, 3); + inst_cream->opcode_1 = BITS(inst, 21, 23); + inst_cream->opcode_2 = BITS(inst, 5, 7); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->inst = inst; + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MCRR"); } ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); - mla_inst *inst_cream = (mla_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); + mla_inst *inst_cream = (mla_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->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 12, 15); - inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rm = BITS(inst, 0, 3); - if (CHECK_RM || CHECK_RN || CHECK_RS) - inst_base->load_r15 = 1; + if (CHECK_RM || CHECK_RN || CHECK_RS) + inst_base->load_r15 = 1; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); - mov_inst *inst_cream = (mov_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); + mov_inst *inst_cream = (mov_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_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); - mrc_inst *inst_cream = (mrc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - - inst_cream->crn = BITS(inst, 16, 19); - inst_cream->crm = BITS(inst, 0, 3); - inst_cream->opcode_1 = BITS(inst, 21, 23); - inst_cream->opcode_2 = BITS(inst, 5, 7); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->inst = inst; - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); + mrc_inst *inst_cream = (mrc_inst *)inst_base->component; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + + inst_cream->crn = BITS(inst, 16, 19); + inst_cream->crm = BITS(inst, 0, 3); + inst_cream->opcode_1 = BITS(inst, 21, 23); + inst_cream->opcode_2 = BITS(inst, 5, 7); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->inst = inst; + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MRRC"); } ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); - mrs_inst *inst_cream = (mrs_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); + mrs_inst *inst_cream = (mrs_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_cream->Rd = BITS(inst, 12, 15); - inst_cream->R = BIT(inst, 22); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->R = BIT(inst, 22); - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); - msr_inst *inst_cream = (msr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); + msr_inst *inst_cream = (msr_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_cream->field_mask = BITS(inst, 16, 19); - inst_cream->R = BIT(inst, 22); - inst_cream->inst = inst; + inst_cream->field_mask = BITS(inst, 16, 19); + inst_cream->R = BIT(inst, 22); + inst_cream->inst = inst; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); - mul_inst *inst_cream = (mul_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); + mul_inst *inst_cream = (mul_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->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rd = BITS(inst, 16, 19); - if (CHECK_RM || CHECK_RS) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM || CHECK_RS) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); - mvn_inst *inst_cream = (mvn_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); + mvn_inst *inst_cream = (mvn_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_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); - orr_inst *inst_cream = (orr_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - - if (CHECK_RN) - inst_base->load_r15 = 1; - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); + orr_inst *inst_cream = (orr_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + + if (CHECK_RN) + inst_base->load_r15 = 1; + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; +} + +ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) +{ + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); + pkh_inst *inst_cream = (pkh_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->Rd = BITS(inst, 12, 15); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->imm = BITS(inst, 7, 11); + + return inst_base; +} + +ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(pkhbt)(inst, index); +} + ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); - - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - inst_base->load_r15 = 0; - - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; + inst_base->load_r15 = 0; + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* const 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->load_r15 = 0; + + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->op1 = BITS(inst, 20, 21); + inst_cream->op2 = BITS(inst, 5, 7); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(qadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(qadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(qadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(qadd8)(inst, index); +} +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 *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_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); - return inst_base; + 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; + 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_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); - return inst_base; + return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} +ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } +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) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); - rsb_inst *inst_cream = (rsb_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (CHECK_RN) - inst_base->load_r15 = 1; - - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); + rsb_inst *inst_cream = (rsb_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (CHECK_RN) + inst_base->load_r15 = 1; + + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); - rsc_inst *inst_cream = (rsc_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (CHECK_RN) - inst_base->load_r15 = 1; - - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); + rsc_inst *inst_cream = (rsc_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (CHECK_RN) + inst_base->load_r15 = 1; + + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* const 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->load_r15 = 0; + + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->op1 = BITS(inst, 20, 21); + inst_cream->op2 = BITS(inst, 5, 7); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(sadd16)(inst, index); +} ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); - sbc_inst *inst_cream = (sbc_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (CHECK_RN) - inst_base->load_r15 = 1; - - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); + sbc_inst *inst_cream = (sbc_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (CHECK_RN) + inst_base->load_r15 = 1; + + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* const 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->load_r15 = 0; + + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + 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(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD8"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADDSUBX"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB16"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB8"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); } ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); - smla_inst *inst_cream = (smla_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); + smla_inst *inst_cream = (smla_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->x = BIT(inst, 5); - inst_cream->y = BIT(inst, 6); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Rn = BITS(inst, 12, 15); + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Rn = BITS(inst, 12, 15); - return inst_base; + 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; + 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; - 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->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, 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); - if (CHECK_RM ) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM ) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); - umlal_inst *inst_cream = (umlal_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->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->RdHi = BITS(inst, 16, 19); - inst_cream->RdLo = BITS(inst, 12, 15); - - if (CHECK_RM || CHECK_RS) - inst_base->load_r15 = 1; - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); + umlal_inst *inst_cream = (umlal_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->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->RdHi = BITS(inst, 16, 19); + inst_cream->RdLo = BITS(inst, 12, 15); + + if (CHECK_RM || CHECK_RS) + 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(smul)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); - smul_inst *inst_cream = (smul_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); + smul_inst *inst_cream = (smul_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->Rd = BITS(inst, 16, 19); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->x = BIT(inst, 5); - inst_cream->y = BIT(inst, 6); + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); - if (CHECK_RM || CHECK_RS) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM || CHECK_RS) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); - umull_inst *inst_cream = (umull_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); + umull_inst *inst_cream = (umull_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->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->RdHi = BITS(inst, 16, 19); - inst_cream->RdLo = BITS(inst, 12, 15); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->RdHi = BITS(inst, 16, 19); + inst_cream->RdLo = BITS(inst, 12, 15); - if (CHECK_RM || CHECK_RS) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM || CHECK_RS) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(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; - inst_base->load_r15 = 0; - - inst_cream->m = BIT(inst, 6); - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rn = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 16, 19); - - if (CHECK_RM || CHECK_RN) - inst_base->load_r15 = 1; - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + 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; + inst_base->load_r15 = 0; + + inst_cream->m = BIT(inst, 6); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 16, 19); + + if (CHECK_RM || CHECK_RN) + 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) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst)); + ssat_inst* const inst_cream = (ssat_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->Rn = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->imm5 = BITS(inst, 7, 11); + inst_cream->sat_imm = BITS(inst, 16, 20); + inst_cream->shift_type = BIT(inst, 6); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT16"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(sadd16)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(sadd16)(inst, index); +} ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(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(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_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); - return inst_base; + inst_cream->inst = inst; + inst_cream->get_addr = get_calc_addr_op(inst); + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); - sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); + sxtb_inst *inst_cream = (sxtb_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->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->rotate = BITS(inst, 10, 11); - if (CHECK_RM) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(str)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); - uxth_inst *inst_cream = (uxth_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); + uxth_inst *inst_cream = (uxth_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->Rd = BITS(inst, 12, 15); - inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rm = BITS(inst, 0, 3); - if (CHECK_RM) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); - uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); + uxtab_inst *inst_cream = (uxtab_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->Rd = BITS(inst, 12, 15); - inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(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 (I_BIT == 0) { - inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); - } else { - DEBUG_MSG; - } - - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + 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 (I_BIT == 0) { + inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else { + DEBUG_MSG; + } + + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } 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(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_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); + 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; + 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; + 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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(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(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_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); + 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; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(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; - if (I_BIT == 0) { - inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); - } else { - DEBUG_MSG; - } + 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; + if (I_BIT == 0) { + inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else { + DEBUG_MSG; + } - if (BITS(inst, 12, 15) == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (BITS(inst, 12, 15) == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); - sub_inst *inst_cream = (sub_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - if (CHECK_RN) - inst_base->load_r15 = 1; - - return inst_base; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); + sub_inst *inst_cream = (sub_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + if (CHECK_RN) + inst_base->load_r15 = 1; + + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); - swi_inst *inst_cream = (swi_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); + swi_inst *inst_cream = (swi_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_cream->num = BITS(inst, 0, 23); - return inst_base; + inst_cream->num = BITS(inst, 0, 23); + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); - swp_inst *inst_cream = (swp_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); + swp_inst *inst_cream = (swp_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_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); - swp_inst *inst_cream = (swp_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); + swp_inst *inst_cream = (swp_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_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - return inst_base; + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); - sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); + sxtab_inst *inst_cream = (sxtab_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->Rd = BITS(inst, 12, 15); - inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); - return inst_base; + return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} +ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); } ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ - DEBUG_LOG(ARM11, "in func %s, SXTAH untested\n", __func__); - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); - sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; + LOG_WARNING(Core_ARM11, "SXTAH untested"); + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); + sxtah_inst *inst_cream = (sxtah_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->Rd = BITS(inst, 12, 15); - inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); - return inst_base; + return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} +ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); } ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); - teq_inst *inst_cream = (teq_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); + teq_inst *inst_cream = (teq_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->I = BIT(inst, 25); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); + inst_cream->I = BIT(inst, 25); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); - if (CHECK_RN) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RN) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); - tst_inst *inst_cream = (tst_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->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = get_shtop(inst); - if (inst_cream->Rd == 15) { - inst_base->br = INDIRECT_BRANCH; - } - - if (CHECK_RN) - inst_base->load_r15 = 1; - return inst_base; -} -ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); + tst_inst *inst_cream = (tst_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->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->shifter_operand = BITS(inst, 0, 11); + inst_cream->shtop_func = get_shtop(inst); + if (inst_cream->Rd == 15) { + inst_base->br = INDIRECT_BRANCH; + } + + if (CHECK_RN) + inst_base->load_r15 = 1; + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* const 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->load_r15 = 0; + + inst_cream->op1 = BITS(inst, 20, 21); + inst_cream->op2 = BITS(inst, 5, 7); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uhadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uhadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uhadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uhadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uhadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); + umaal_inst* const inst_cream = (umaal_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); + + if (CHECK_RM || CHECK_RN) + inst_base->load_r15 = 1; + + return inst_base; +} ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); + umlal_inst *inst_cream = (umlal_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->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->RdHi = BITS(inst, 16, 19); + inst_cream->RdLo = BITS(inst, 12, 15); - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->RdHi = BITS(inst, 16, 19); - inst_cream->RdLo = BITS(inst, 12, 15); + if (CHECK_RM || CHECK_RS) + inst_base->load_r15 = 1; - if (CHECK_RM || CHECK_RS) - inst_base->load_r15 = 1; - return inst_base; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); - umull_inst *inst_cream = (umull_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); + umull_inst *inst_cream = (umull_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->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->RdHi = BITS(inst, 16, 19); - inst_cream->RdLo = BITS(inst, 12, 15); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->RdHi = BITS(inst, 16, 19); + inst_cream->RdLo = BITS(inst, 12, 15); - if (CHECK_RM || CHECK_RS) - inst_base->load_r15 = 1; - return inst_base; + if (CHECK_RM || CHECK_RS) + inst_base->load_r15 = 1; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); - b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); + b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; - inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); - //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; - return inst_base; + inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); + + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; + + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); - b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); + b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; - inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); - inst_cream->cond = ((tinst >> 8) & 0xf); - //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; - return inst_base; + inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); + inst_cream->cond = ((tinst >> 8) & 0xf); + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; + + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); - bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); + bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; - inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); - //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); + inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); - inst_base->idx = index; - inst_base->br = NON_BRANCH; - return inst_base; + inst_base->idx = index; + inst_base->br = NON_BRANCH; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); - bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); + bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; + + inst_cream->imm = (tinst & 0x07FF) << 1; - inst_cream->imm = (tinst & 0x07FF) << 1; - //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; - return inst_base; + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; + return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); - blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); + blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; - inst_cream->imm = (tinst & 0x07FF) << 1; - //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); - inst_cream->instr = tinst; - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; - return inst_base; + inst_cream->imm = (tinst & 0x07FF) << 1; + inst_cream->instr = tinst; + + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; + return inst_base; } -ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} -ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;} +ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* const 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->load_r15 = 0; + + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->op1 = BITS(inst, 20, 21); + inst_cream->op2 = BITS(inst, 5, 7); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uqadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uqadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uqadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uqadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uqadd8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* const 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->load_r15 = 0; + inst_cream->op1 = BITS(inst, 20, 24); + inst_cream->op2 = BITS(inst, 5, 7); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Ra = BITS(inst, 12, 15); -/* Floating point VFPv3 structures and instructions */ + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(usada8)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(ssat)(inst, index); +} +ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); } + +ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) +{ + arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); + uxtab_inst* const inst_cream = (uxtab_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->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->rotate = BITS(inst, 10, 11); + + return inst_base; +} +ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) +{ + return INTERPRETER_TRANSLATE(uxtab16)(inst, index); +} + +// Floating point VFPv3 structures and instructions #define VFP_INTERPRETER_STRUCT #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" @@ -3149,324 +3202,288 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_L #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" #undef VFP_INTERPRETER_TRANS - - typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); const transop_fp_t arm_instruction_trans[] = { - #define VFP_INTERPRETER_TABLE - #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" - #undef VFP_INTERPRETER_TABLE - INTERPRETER_TRANSLATE(srs), - INTERPRETER_TRANSLATE(rfe), - INTERPRETER_TRANSLATE(bkpt), - INTERPRETER_TRANSLATE(blx), - INTERPRETER_TRANSLATE(cps), - INTERPRETER_TRANSLATE(pld), - INTERPRETER_TRANSLATE(setend), - INTERPRETER_TRANSLATE(clrex), - INTERPRETER_TRANSLATE(rev16), - INTERPRETER_TRANSLATE(usad8), - INTERPRETER_TRANSLATE(sxtb), - INTERPRETER_TRANSLATE(uxtb), - INTERPRETER_TRANSLATE(sxth), - INTERPRETER_TRANSLATE(sxtb16), - INTERPRETER_TRANSLATE(uxth), - INTERPRETER_TRANSLATE(uxtb16), - INTERPRETER_TRANSLATE(cpy), - INTERPRETER_TRANSLATE(uxtab), - INTERPRETER_TRANSLATE(ssub8), - INTERPRETER_TRANSLATE(shsub8), - INTERPRETER_TRANSLATE(ssubaddx), - INTERPRETER_TRANSLATE(strex), - INTERPRETER_TRANSLATE(strexb), - INTERPRETER_TRANSLATE(swp), - INTERPRETER_TRANSLATE(swpb), - INTERPRETER_TRANSLATE(ssub16), - INTERPRETER_TRANSLATE(ssat16), - INTERPRETER_TRANSLATE(shsubaddx), - INTERPRETER_TRANSLATE(qsubaddx), - INTERPRETER_TRANSLATE(shaddsubx), - INTERPRETER_TRANSLATE(shadd8), - INTERPRETER_TRANSLATE(shadd16), - INTERPRETER_TRANSLATE(sel), - INTERPRETER_TRANSLATE(saddsubx), - INTERPRETER_TRANSLATE(sadd8), - INTERPRETER_TRANSLATE(sadd16), - INTERPRETER_TRANSLATE(shsub16), - INTERPRETER_TRANSLATE(umaal), - INTERPRETER_TRANSLATE(uxtab16), - INTERPRETER_TRANSLATE(usubaddx), - INTERPRETER_TRANSLATE(usub8), - INTERPRETER_TRANSLATE(usub16), - INTERPRETER_TRANSLATE(usat16), - INTERPRETER_TRANSLATE(usada8), - INTERPRETER_TRANSLATE(uqsubaddx), - INTERPRETER_TRANSLATE(uqsub8), - INTERPRETER_TRANSLATE(uqsub16), - INTERPRETER_TRANSLATE(uqaddsubx), - INTERPRETER_TRANSLATE(uqadd8), - INTERPRETER_TRANSLATE(uqadd16), - INTERPRETER_TRANSLATE(sxtab), - INTERPRETER_TRANSLATE(uhsubaddx), - INTERPRETER_TRANSLATE(uhsub8), - INTERPRETER_TRANSLATE(uhsub16), - INTERPRETER_TRANSLATE(uhaddsubx), - INTERPRETER_TRANSLATE(uhadd8), - INTERPRETER_TRANSLATE(uhadd16), - INTERPRETER_TRANSLATE(uaddsubx), - INTERPRETER_TRANSLATE(uadd8), - INTERPRETER_TRANSLATE(uadd16), - INTERPRETER_TRANSLATE(sxtah), - INTERPRETER_TRANSLATE(sxtab16), - INTERPRETER_TRANSLATE(qadd8), - INTERPRETER_TRANSLATE(bxj), - INTERPRETER_TRANSLATE(clz), - INTERPRETER_TRANSLATE(uxtah), - INTERPRETER_TRANSLATE(bx), - INTERPRETER_TRANSLATE(rev), - INTERPRETER_TRANSLATE(blx), - INTERPRETER_TRANSLATE(revsh), - INTERPRETER_TRANSLATE(qadd), - INTERPRETER_TRANSLATE(qadd16), - INTERPRETER_TRANSLATE(qaddsubx), - INTERPRETER_TRANSLATE(ldrex), - INTERPRETER_TRANSLATE(qdadd), - INTERPRETER_TRANSLATE(qdsub), - INTERPRETER_TRANSLATE(qsub), - INTERPRETER_TRANSLATE(ldrexb), - INTERPRETER_TRANSLATE(qsub8), - INTERPRETER_TRANSLATE(qsub16), - INTERPRETER_TRANSLATE(smuad), - INTERPRETER_TRANSLATE(smmul), - INTERPRETER_TRANSLATE(smusd), - INTERPRETER_TRANSLATE(smlsd), - INTERPRETER_TRANSLATE(smlsld), - INTERPRETER_TRANSLATE(smmla), - INTERPRETER_TRANSLATE(smmls), - INTERPRETER_TRANSLATE(smlald), - INTERPRETER_TRANSLATE(smlad), - INTERPRETER_TRANSLATE(smlaw), - INTERPRETER_TRANSLATE(smulw), - INTERPRETER_TRANSLATE(pkhtb), - INTERPRETER_TRANSLATE(pkhbt), - INTERPRETER_TRANSLATE(smul), - INTERPRETER_TRANSLATE(smlalxy), - INTERPRETER_TRANSLATE(smla), - INTERPRETER_TRANSLATE(mcrr), - INTERPRETER_TRANSLATE(mrrc), - INTERPRETER_TRANSLATE(cmp), - INTERPRETER_TRANSLATE(tst), - INTERPRETER_TRANSLATE(teq), - INTERPRETER_TRANSLATE(cmn), - INTERPRETER_TRANSLATE(smull), - INTERPRETER_TRANSLATE(umull), - INTERPRETER_TRANSLATE(umlal), - INTERPRETER_TRANSLATE(smlal), - INTERPRETER_TRANSLATE(mul), - INTERPRETER_TRANSLATE(mla), - INTERPRETER_TRANSLATE(ssat), - INTERPRETER_TRANSLATE(usat), - INTERPRETER_TRANSLATE(mrs), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(and), - INTERPRETER_TRANSLATE(bic), - INTERPRETER_TRANSLATE(ldm), - INTERPRETER_TRANSLATE(eor), - INTERPRETER_TRANSLATE(add), - INTERPRETER_TRANSLATE(rsb), - INTERPRETER_TRANSLATE(rsc), - INTERPRETER_TRANSLATE(sbc), - INTERPRETER_TRANSLATE(adc), - INTERPRETER_TRANSLATE(sub), - INTERPRETER_TRANSLATE(orr), - INTERPRETER_TRANSLATE(mvn), - INTERPRETER_TRANSLATE(mov), - INTERPRETER_TRANSLATE(stm), - INTERPRETER_TRANSLATE(ldm), - INTERPRETER_TRANSLATE(ldrsh), - INTERPRETER_TRANSLATE(stm), - INTERPRETER_TRANSLATE(ldm), - INTERPRETER_TRANSLATE(ldrsb), - INTERPRETER_TRANSLATE(strd), - INTERPRETER_TRANSLATE(ldrh), - INTERPRETER_TRANSLATE(strh), - INTERPRETER_TRANSLATE(ldrd), - INTERPRETER_TRANSLATE(strt), - INTERPRETER_TRANSLATE(strbt), - INTERPRETER_TRANSLATE(ldrbt), - INTERPRETER_TRANSLATE(ldrt), - INTERPRETER_TRANSLATE(mrc), - INTERPRETER_TRANSLATE(mcr), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(ldrb), - INTERPRETER_TRANSLATE(strb), - INTERPRETER_TRANSLATE(ldr), - INTERPRETER_TRANSLATE(ldrcond), - INTERPRETER_TRANSLATE(str), - INTERPRETER_TRANSLATE(cdp), - INTERPRETER_TRANSLATE(stc), - INTERPRETER_TRANSLATE(ldc), - INTERPRETER_TRANSLATE(swi), - INTERPRETER_TRANSLATE(bbl), - /* All the thumb instructions should be placed the end of table */ - INTERPRETER_TRANSLATE(b_2_thumb), - INTERPRETER_TRANSLATE(b_cond_thumb), - INTERPRETER_TRANSLATE(bl_1_thumb), - INTERPRETER_TRANSLATE(bl_2_thumb), - INTERPRETER_TRANSLATE(blx_1_thumb) + INTERPRETER_TRANSLATE(vmla), + INTERPRETER_TRANSLATE(vmls), + INTERPRETER_TRANSLATE(vnmla), + INTERPRETER_TRANSLATE(vnmla), + INTERPRETER_TRANSLATE(vnmls), + INTERPRETER_TRANSLATE(vnmul), + INTERPRETER_TRANSLATE(vmul), + INTERPRETER_TRANSLATE(vadd), + INTERPRETER_TRANSLATE(vsub), + INTERPRETER_TRANSLATE(vdiv), + INTERPRETER_TRANSLATE(vmovi), + INTERPRETER_TRANSLATE(vmovr), + INTERPRETER_TRANSLATE(vabs), + INTERPRETER_TRANSLATE(vneg), + INTERPRETER_TRANSLATE(vsqrt), + INTERPRETER_TRANSLATE(vcmp), + INTERPRETER_TRANSLATE(vcmp2), + INTERPRETER_TRANSLATE(vcvtbds), + INTERPRETER_TRANSLATE(vcvtbff), + INTERPRETER_TRANSLATE(vcvtbfi), + INTERPRETER_TRANSLATE(vmovbrs), + INTERPRETER_TRANSLATE(vmsr), + INTERPRETER_TRANSLATE(vmovbrc), + INTERPRETER_TRANSLATE(vmrs), + INTERPRETER_TRANSLATE(vmovbcr), + INTERPRETER_TRANSLATE(vmovbrrss), + INTERPRETER_TRANSLATE(vmovbrrd), + INTERPRETER_TRANSLATE(vstr), + INTERPRETER_TRANSLATE(vpush), + INTERPRETER_TRANSLATE(vstm), + INTERPRETER_TRANSLATE(vpop), + INTERPRETER_TRANSLATE(vldr), + INTERPRETER_TRANSLATE(vldm), + + INTERPRETER_TRANSLATE(srs), + INTERPRETER_TRANSLATE(rfe), + INTERPRETER_TRANSLATE(bkpt), + INTERPRETER_TRANSLATE(blx), + INTERPRETER_TRANSLATE(cps), + INTERPRETER_TRANSLATE(pld), + INTERPRETER_TRANSLATE(setend), + INTERPRETER_TRANSLATE(clrex), + INTERPRETER_TRANSLATE(rev16), + INTERPRETER_TRANSLATE(usad8), + INTERPRETER_TRANSLATE(sxtb), + INTERPRETER_TRANSLATE(uxtb), + INTERPRETER_TRANSLATE(sxth), + INTERPRETER_TRANSLATE(sxtb16), + INTERPRETER_TRANSLATE(uxth), + INTERPRETER_TRANSLATE(uxtb16), + INTERPRETER_TRANSLATE(cpy), + INTERPRETER_TRANSLATE(uxtab), + INTERPRETER_TRANSLATE(ssub8), + INTERPRETER_TRANSLATE(shsub8), + INTERPRETER_TRANSLATE(ssubaddx), + INTERPRETER_TRANSLATE(strex), + INTERPRETER_TRANSLATE(strexb), + INTERPRETER_TRANSLATE(swp), + INTERPRETER_TRANSLATE(swpb), + INTERPRETER_TRANSLATE(ssub16), + INTERPRETER_TRANSLATE(ssat16), + INTERPRETER_TRANSLATE(shsubaddx), + INTERPRETER_TRANSLATE(qsubaddx), + INTERPRETER_TRANSLATE(shaddsubx), + INTERPRETER_TRANSLATE(shadd8), + INTERPRETER_TRANSLATE(shadd16), + INTERPRETER_TRANSLATE(sel), + INTERPRETER_TRANSLATE(saddsubx), + INTERPRETER_TRANSLATE(sadd8), + INTERPRETER_TRANSLATE(sadd16), + INTERPRETER_TRANSLATE(shsub16), + INTERPRETER_TRANSLATE(umaal), + INTERPRETER_TRANSLATE(uxtab16), + INTERPRETER_TRANSLATE(usubaddx), + INTERPRETER_TRANSLATE(usub8), + INTERPRETER_TRANSLATE(usub16), + INTERPRETER_TRANSLATE(usat16), + INTERPRETER_TRANSLATE(usada8), + INTERPRETER_TRANSLATE(uqsubaddx), + INTERPRETER_TRANSLATE(uqsub8), + INTERPRETER_TRANSLATE(uqsub16), + INTERPRETER_TRANSLATE(uqaddsubx), + INTERPRETER_TRANSLATE(uqadd8), + INTERPRETER_TRANSLATE(uqadd16), + INTERPRETER_TRANSLATE(sxtab), + INTERPRETER_TRANSLATE(uhsubaddx), + INTERPRETER_TRANSLATE(uhsub8), + INTERPRETER_TRANSLATE(uhsub16), + INTERPRETER_TRANSLATE(uhaddsubx), + INTERPRETER_TRANSLATE(uhadd8), + INTERPRETER_TRANSLATE(uhadd16), + INTERPRETER_TRANSLATE(uaddsubx), + INTERPRETER_TRANSLATE(uadd8), + INTERPRETER_TRANSLATE(uadd16), + INTERPRETER_TRANSLATE(sxtah), + INTERPRETER_TRANSLATE(sxtab16), + INTERPRETER_TRANSLATE(qadd8), + INTERPRETER_TRANSLATE(bxj), + INTERPRETER_TRANSLATE(clz), + INTERPRETER_TRANSLATE(uxtah), + INTERPRETER_TRANSLATE(bx), + INTERPRETER_TRANSLATE(rev), + INTERPRETER_TRANSLATE(blx), + INTERPRETER_TRANSLATE(revsh), + INTERPRETER_TRANSLATE(qadd), + INTERPRETER_TRANSLATE(qadd16), + INTERPRETER_TRANSLATE(qaddsubx), + INTERPRETER_TRANSLATE(ldrex), + INTERPRETER_TRANSLATE(qdadd), + INTERPRETER_TRANSLATE(qdsub), + INTERPRETER_TRANSLATE(qsub), + INTERPRETER_TRANSLATE(ldrexb), + INTERPRETER_TRANSLATE(qsub8), + INTERPRETER_TRANSLATE(qsub16), + INTERPRETER_TRANSLATE(smuad), + INTERPRETER_TRANSLATE(smmul), + INTERPRETER_TRANSLATE(smusd), + INTERPRETER_TRANSLATE(smlsd), + INTERPRETER_TRANSLATE(smlsld), + INTERPRETER_TRANSLATE(smmla), + INTERPRETER_TRANSLATE(smmls), + INTERPRETER_TRANSLATE(smlald), + INTERPRETER_TRANSLATE(smlad), + INTERPRETER_TRANSLATE(smlaw), + INTERPRETER_TRANSLATE(smulw), + INTERPRETER_TRANSLATE(pkhtb), + INTERPRETER_TRANSLATE(pkhbt), + INTERPRETER_TRANSLATE(smul), + INTERPRETER_TRANSLATE(smlalxy), + INTERPRETER_TRANSLATE(smla), + INTERPRETER_TRANSLATE(mcrr), + INTERPRETER_TRANSLATE(mrrc), + INTERPRETER_TRANSLATE(cmp), + INTERPRETER_TRANSLATE(tst), + INTERPRETER_TRANSLATE(teq), + INTERPRETER_TRANSLATE(cmn), + INTERPRETER_TRANSLATE(smull), + INTERPRETER_TRANSLATE(umull), + INTERPRETER_TRANSLATE(umlal), + INTERPRETER_TRANSLATE(smlal), + INTERPRETER_TRANSLATE(mul), + INTERPRETER_TRANSLATE(mla), + INTERPRETER_TRANSLATE(ssat), + INTERPRETER_TRANSLATE(usat), + INTERPRETER_TRANSLATE(mrs), + INTERPRETER_TRANSLATE(msr), + INTERPRETER_TRANSLATE(and), + INTERPRETER_TRANSLATE(bic), + INTERPRETER_TRANSLATE(ldm), + INTERPRETER_TRANSLATE(eor), + INTERPRETER_TRANSLATE(add), + INTERPRETER_TRANSLATE(rsb), + INTERPRETER_TRANSLATE(rsc), + INTERPRETER_TRANSLATE(sbc), + INTERPRETER_TRANSLATE(adc), + INTERPRETER_TRANSLATE(sub), + INTERPRETER_TRANSLATE(orr), + INTERPRETER_TRANSLATE(mvn), + INTERPRETER_TRANSLATE(mov), + INTERPRETER_TRANSLATE(stm), + INTERPRETER_TRANSLATE(ldm), + INTERPRETER_TRANSLATE(ldrsh), + INTERPRETER_TRANSLATE(stm), + INTERPRETER_TRANSLATE(ldm), + INTERPRETER_TRANSLATE(ldrsb), + INTERPRETER_TRANSLATE(strd), + INTERPRETER_TRANSLATE(ldrh), + INTERPRETER_TRANSLATE(strh), + INTERPRETER_TRANSLATE(ldrd), + INTERPRETER_TRANSLATE(strt), + INTERPRETER_TRANSLATE(strbt), + INTERPRETER_TRANSLATE(ldrbt), + INTERPRETER_TRANSLATE(ldrt), + INTERPRETER_TRANSLATE(mrc), + INTERPRETER_TRANSLATE(mcr), + INTERPRETER_TRANSLATE(msr), + INTERPRETER_TRANSLATE(ldrb), + INTERPRETER_TRANSLATE(strb), + INTERPRETER_TRANSLATE(ldr), + INTERPRETER_TRANSLATE(ldrcond), + INTERPRETER_TRANSLATE(str), + INTERPRETER_TRANSLATE(cdp), + INTERPRETER_TRANSLATE(stc), + INTERPRETER_TRANSLATE(ldc), + INTERPRETER_TRANSLATE(swi), + INTERPRETER_TRANSLATE(bbl), + // All the thumb instructions should be placed the end of table + INTERPRETER_TRANSLATE(b_2_thumb), + INTERPRETER_TRANSLATE(b_cond_thumb), + INTERPRETER_TRANSLATE(bl_1_thumb), + INTERPRETER_TRANSLATE(bl_2_thumb), + INTERPRETER_TRANSLATE(blx_1_thumb) }; -typedef map<unsigned int, int> bb_map; -bb_map CreamCache[65536]; -bb_map ProfileCache[65536]; - -//#define USE_DUMMY_CACHE +typedef std::unordered_map<u32, int> bb_map; +bb_map CreamCache; -#ifdef USE_DUMMY_CACHE -unsigned int DummyCache[0x100000]; -#endif - -#define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536) -void insert_bb(unsigned int addr, int start) -{ -#ifdef USE_DUMMY_CACHE - DummyCache[addr] = start; -#else -// CreamCache[addr] = start; - CreamCache[HASH(addr)][addr] = start; -#endif +void insert_bb(unsigned int addr, int start) { + CreamCache[addr] = start; } #define TRANS_THRESHOLD 65000 -int find_bb(unsigned int addr, int &start) -{ - int ret = -1; -#ifdef USE_DUMMY_CACHE - start = DummyCache[addr]; - if (start) { - ret = 0; - } else - ret = -1; -#else - bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr); - if (it != CreamCache[HASH(addr)].end()) { - start = static_cast<int>(it->second); - ret = 0; -#if HYBRID_MODE -#if PROFILE -#else - /* increase the bb counter */ - if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){ - push_to_compiled(cpu, addr); - } -#endif -#endif - } else { - ret = -1; - } -#endif - return ret; +int find_bb(unsigned int addr, int &start) { + int ret = -1; + bb_map::const_iterator it = CreamCache.find(addr); + if (it != CreamCache.end()) { + start = static_cast<int>(it->second); + ret = 0; + } else { + ret = -1; + } + return ret; } - enum { - FETCH_SUCCESS, - FETCH_FAILURE + FETCH_SUCCESS, + FETCH_FAILURE }; + static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr, uint32_t *arm_inst, uint32_t* inst_size, ARM_INST_PTR* ptr_inst_base){ - /* Check if in Thumb mode. */ - tdstate ret; - ret = thumb_translate (addr, inst, arm_inst, inst_size); - if(ret == t_branch){ - /* FIXME, endian should be judged */ - uint32 tinstr; - if((addr & 0x3) != 0) - tinstr = inst >> 16; - else - tinstr = inst & 0xFFFF; - - //tinstr = inst & 0xFFFF; - int inst_index; - /* table_length */ - int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); - - switch((tinstr & 0xF800) >> 11){ - /* we will translate the thumb instruction directly here */ - /* we will translate the thumb instruction directly here */ - case 26: - case 27: - if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ - uint32 cond = (tinstr & 0x0F00) >> 8; - inst_index = table_length - 4; - //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); - *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); - } - else{ - /* something wrong */ - DEBUG_LOG(ARM11, "In %s, thumb decoder error\n", __FUNCTION__); - } - break; - case 28: - /* Branch 2, unconditional branch */ - inst_index = table_length - 5; - //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); - *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); - break; - - case 8: - case 29: - /* For BLX 1 thumb instruction*/ - inst_index = table_length - 1; - //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); - *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); - break; - case 30: - /* For BL 1 thumb instruction*/ - inst_index = table_length - 3; - //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); - *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); - break; - case 31: - /* For BL 2 thumb instruction*/ - inst_index = table_length - 2; - //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); - *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); - break; - default: - ret = t_undefined; - break; - } - } - return ret; -} - -#if 0 -int FetchInst(cpu_t *core, unsigned int &inst) -{ - //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); - arm_processor *cpu = (arm_processor *)(core->cpu_data->obj); -// fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32); - fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32); - if (!core->is_user_mode) { - if (fault) { - cpu->abortSig = true; - cpu->Aborted = ARMul_PrefetchAbortV; - cpu->AbortAddr = cpu->translate_pc; - cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; - cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc; - return FETCH_FAILURE; - } - } - return FETCH_SUCCESS; + // Check if in Thumb mode + tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); + if(ret == t_branch){ + // TODO: FIXME, endian should be judged + uint32 tinstr; + if((addr & 0x3) != 0) + tinstr = inst >> 16; + else + tinstr = inst & 0xFFFF; + + int inst_index; + int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); + + switch((tinstr & 0xF800) >> 11){ + case 26: + case 27: + if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ + uint32 cond = (tinstr & 0x0F00) >> 8; + inst_index = table_length - 4; + *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); + } else { + LOG_ERROR(Core_ARM11, "thumb decoder error"); + } + break; + case 28: + // Branch 2, unconditional branch + inst_index = table_length - 5; + *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); + break; + + case 8: + case 29: + // For BLX 1 thumb instruction + inst_index = table_length - 1; + *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); + break; + case 30: + // For BL 1 thumb instruction + inst_index = table_length - 3; + *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); + break; + case 31: + // For BL 2 thumb instruction + inst_index = table_length - 2; + *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); + break; + default: + ret = t_undefined; + break; + } + } + return ret; } -#endif unsigned int *InstLength; enum { - KEEP_GOING, - FETCH_EXCEPTION + KEEP_GOING, + FETCH_EXCEPTION }; typedef struct instruction_set_encoding_item ISEITEM; @@ -3475,289 +3492,148 @@ extern const ISEITEM arm_instruction[]; vector<uint64_t> code_page_set; -void flush_bb(uint32_t addr) -{ - bb_map::iterator it; - uint32_t start; - - addr &= 0xfffff000; - for (int i = 0; i < 65536; i ++) { - for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) { - start = static_cast<uint32_t>(it->first); - //start = (start >> 12) << 12; - start &= 0xfffff000; - if (start == addr) { - //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); - CreamCache[i].erase(it ++); - } else - ++it; - } - } - - for (int i = 0; i < 65536; i ++) { - for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) { - start = static_cast<uint32_t>(it->first); - //start = (start >> 12) << 12; - start &= 0xfffff000; - if (start == addr) { - //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); - ProfileCache[i].erase(it ++); - } else - ++it; - } - } - - //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr); -} - -//static uint32_t get_bank_addr(void *addr) -//{ -// uint64_t address = (uint64_t)addr; -// uint64_t bank0 = get_dma_addr(BANK0_START); -// if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) { -// //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr); -// return ((uint64_t)addr - bank0) + BANK0_START; -// } -// return 0; -//} - -/* shenoubang add win32 2012-6-12 */ -//#ifndef __WIN32__ -//static void flush_code_cache(int signal_number, siginfo_t *si, void *unused) -//{ -// DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr); -// uint64_t addr = (uint64_t)si->si_addr; -// addr = (addr >> 12) << 12; -// skyeye_backtrace(); -// #if 0 -// if (addr == 0) { -// return; -// } -// const vector<uint64_t>::iterator it = find(code_page_set.begin(), -// code_page_set.end(), -// (uint64_t)addr); -// if (it != code_page_set.end()) { -// code_page_set.erase(it); -// } -// mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE); -// //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr); -// uint32_t phys_addr = get_bank_addr((void *)addr); -//// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr); -// flush_bb(phys_addr); -// flush_bb(phys_addr + 4096); -//#if HYBRID_MODE -// /* flush the translated BB of dyncom */ -// clear_translated_cache(phys_addr); -//#endif -// #endif -//} -//#endif /* shenoubang */ - -//void protect_code_page(uint32_t addr) -//{ -// void *mem_ptr = (void *)get_dma_addr(addr); -// mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL); -// -// const vector<uint64_t>::iterator it = find(code_page_set.begin(), -// code_page_set.end(), -// (uint64_t)mem_ptr); -// if (it != code_page_set.end()) { -// return; -// } -// //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr); -// /* shenoubang add win32 2012-6-12 */ -//#ifndef __WIN32__ -// struct sigaction sa; -// -// memset(&sa, 0, sizeof(sa)); -// sa.sa_flags = SA_RESTART | SA_SIGINFO; -// sa.sa_sigaction = &flush_code_cache; -// sigaction(SIGSEGV, &sa, NULL); -// -// //mprotect(mem_ptr, 4096, PROT_READ); -// -// code_page_set.push_back((uint64_t)mem_ptr); -//#endif /* shenoubang */ -//} - - - -int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) -{ - /* Decode instruction, get index */ - /* Allocate memory and init InsCream */ - /* Go on next, until terminal instruction */ - /* Save start addr of basicblock in CreamCache */ - //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); - //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj); - ARM_INST_PTR inst_base = NULL; - unsigned int inst, inst_size = 4; - int idx; - int ret = NON_BRANCH; - int thumb = 0; - /* instruction size of basic block */ - int size = 0; - /* (R15 - 8) ? */ - //cpu->translate_pc = cpu->Reg[15]; - bb_start = top; - - if (cpu->TFlag) - thumb = THUMB; - - addr_t phys_addr; - addr_t pc_start; - fault_t fault = NO_FAULT; - //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB); - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if(fault != NO_FAULT){ - cpu->abortSig = true; - cpu->Aborted = ARMul_PrefetchAbortV; - cpu->AbortAddr = addr; - cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; - cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; - return FETCH_EXCEPTION; - } - pc_start = phys_addr; - //phys_addr = get_dma_addr(phys_addr); - while(ret == NON_BRANCH) { - /* shenoubang add win32 2012-6-14 */ -#ifdef __WIN32__ - mem_bank_t* bank; - if (bank = bank_ptr(addr)) { - bank->bank_read(32, phys_addr, &inst); - } - else { - DEBUG_LOG(ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr); - return FETCH_FAILURE; - } -#else - inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); -#endif - //or_tag(core, phys_addr, TAG_FAST_INTERP); - - /*if (ret == FETCH_FAILURE) { - return FETCH_EXCEPTION; - }*/ - - size ++; - /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */ - if (cpu->TFlag){ - //if(cpu->Cpsr & (1 << THUMB_BIT)){ - uint32_t arm_inst; - tdstate state; - state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); - //or_tag(core, phys_addr, TAG_THUMB); - //DEBUG_LOG(ARM11, "In thumb state, arm_inst=0x%x, inst_size=0x%x, pc=0x%x\n", arm_inst, inst_size, cpu->translate_pc); - /* we have translated the branch instruction of thumb in thumb decoder */ - if(state == t_branch){ - goto translated; - } - inst = arm_inst; - } - - ret = decode_arm_instr(inst, &idx); - if (ret == DECODE_FAILURE) { - DEBUG_LOG(ARM11, "[info] : Decode failure.\tPC : [0x%x]\tInstruction : [%x]\n", phys_addr, inst); - DEBUG_LOG(ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x\n", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); - CITRA_IGNORE_EXIT(-1); - } -// DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name); - inst_base = arm_instruction_trans[idx](inst, idx); -// DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst); -// DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]); -translated: - phys_addr += inst_size; +void flush_bb(uint32_t addr) { + bb_map::iterator it; + uint32_t start; + + addr &= 0xfffff000; + for (it = CreamCache.begin(); it != CreamCache.end(); ) { + start = static_cast<uint32_t>(it->first); + start &= 0xfffff000; + if (start == addr) { + CreamCache.erase(it++); + } else + ++it; + } +} - if ((phys_addr & 0xfff) == 0) { - inst_base->br = END_OF_PAGE; - } - ret = inst_base->br; - }; +int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) { + // Decode instruction, get index + // Allocate memory and init InsCream + // Go on next, until terminal instruction + // Save start addr of basicblock in CreamCache + ARM_INST_PTR inst_base = nullptr; + unsigned int inst, inst_size = 4; + int idx; + int ret = NON_BRANCH; + int thumb = 0; + int size = 0; // instruction size of basic block + bb_start = top; + + if (cpu->TFlag) + thumb = THUMB; + + addr_t phys_addr; + addr_t pc_start; + fault_t fault = NO_FAULT; + fault = check_address_validity(cpu, addr, &phys_addr, 1); + if(fault != NO_FAULT){ + cpu->abortSig = true; + cpu->Aborted = ARMul_PrefetchAbortV; + cpu->AbortAddr = addr; + cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; + cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; + return FETCH_EXCEPTION; + } - //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag); - insert_bb(pc_start, bb_start); - return KEEP_GOING; -} + pc_start = phys_addr; -#define LOG_IN_CLR skyeye_printf_in_color + while(ret == NON_BRANCH) { + inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); -int cmp(const void *x, const void *y) -{ - return *(unsigned long long int*)x - *(unsigned long long int *)y; + size ++; + // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction + if (cpu->TFlag) { + uint32_t arm_inst; + tdstate state; + state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); + // We have translated the branch instruction of thumb in thumb decoder + if(state == t_branch){ + goto translated; + } + inst = arm_inst; + } + + ret = decode_arm_instr(inst, &idx); + if (ret == DECODE_FAILURE) { + LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst); + LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); + CITRA_IGNORE_EXIT(-1); + } + inst_base = arm_instruction_trans[idx](inst, idx); +translated: + phys_addr += inst_size; + + if ((phys_addr & 0xfff) == 0) { + inst_base->br = END_OF_PAGE; + } + ret = inst_base->br; + }; + insert_bb(pc_start, bb_start); + return KEEP_GOING; +} + +#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]); } -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 ++) - DEBUG_LOG(ARM11, "[%d]:%d\n", i, InstLength[i]); -} - -int clz(unsigned int x) -{ - int n; - if (x == 0) return (32); - n = 1; - if ((x >> 16) == 0) { n = n + 16; x = x << 16;} - if ((x >> 24) == 0) { n = n + 8; x = x << 8;} - if ((x >> 28) == 0) { n = n + 4; x = x << 4;} - if ((x >> 30) == 0) { n = n + 2; x = x << 2;} - n = n - (x >> 31); - return n; +int clz(unsigned int x) { + int n; + if (x == 0) return (32); + n = 1; + if ((x >> 16) == 0) { n = n + 16; x = x << 16;} + if ((x >> 24) == 0) { n = n + 8; x = x << 8;} + if ((x >> 28) == 0) { n = n + 4; x = x << 4;} + if ((x >> 30) == 0) { n = n + 2; x = x << 2;} + n = n - (x >> 31); + return n; } unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number); -static bool InAPrivilegedMode(arm_core_t *core) -{ - return (core->Mode != USER32MODE); +static bool InAPrivilegedMode(arm_core_t *core) { + return (core->Mode != USER32MODE); } -/* r15 = r15 + 8 */ -unsigned InterpreterMainLoop(ARMul_State* state) -{ - #define CRn inst_cream->crn - #define OPCODE_2 inst_cream->opcode_2 - #define CRm inst_cream->crm - #define CP15_REG(n) cpu->CP15[CP15(n)] - #define RD cpu->Reg[inst_cream->Rd] - #define RN cpu->Reg[inst_cream->Rn] - #define RM cpu->Reg[inst_cream->Rm] - #define RS cpu->Reg[inst_cream->Rs] - #define RDHI cpu->Reg[inst_cream->RdHi] - #define RDLO cpu->Reg[inst_cream->RdLo] - #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) - #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) - #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) - - #if ENABLE_ICOUNTER - #define INC_ICOUNTER cpu->icounter++; \ - if(cpu->Reg[15] > 0xc0000000) \ - cpu->kernel_icounter++; - //if (debug_function(core)) \ - if (core->check_int_flag) \ - goto END - //DEBUG_LOG(ARM11, "icounter is %llx line is %d pc is %x\n", cpu->icounter, __LINE__, cpu->Reg[15]) - #else - #define INC_ICOUNTER ; - #endif - - #define FETCH_INST if (inst_base->br != NON_BRANCH) \ - goto DISPATCH; \ - inst_base = (arm_inst *)&inst_buf[ptr] -#define INC_PC(l) ptr += sizeof(arm_inst) + l +unsigned InterpreterMainLoop(ARMul_State* state) { + #define CRn inst_cream->crn + #define OPCODE_2 inst_cream->opcode_2 + #define CRm inst_cream->crm + #define CP15_REG(n) cpu->CP15[CP15(n)] + #define RD cpu->Reg[inst_cream->Rd] + #define RN cpu->Reg[inst_cream->Rn] + #define RM cpu->Reg[inst_cream->Rm] + #define RS cpu->Reg[inst_cream->Rs] + #define RDHI cpu->Reg[inst_cream->RdHi] + #define RDLO cpu->Reg[inst_cream->RdLo] + #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) + #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) + #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) + + #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \ + inst_base = (arm_inst *)&inst_buf[ptr] + + #define INC_PC(l) ptr += sizeof(arm_inst) + l // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a // clunky switch statement. @@ -3898,7 +3774,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) case 124: goto PKHTB_INST; \ case 125: goto PKHBT_INST; \ case 126: goto SMUL_INST; \ - case 127: goto SMLAL_INST; \ + case 127: goto SMLALXY_INST; \ case 128: goto SMLA_INST; \ case 129: goto MCRR_INST; \ case 130: goto MRRC_INST; \ @@ -3967,2606 +3843,2586 @@ unsigned InterpreterMainLoop(ARMul_State* state) } #endif - #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) - #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) -// #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \ - (ISNEG(lop) && ISPOS(dst)) || \ - (ISPOS(rop) && ISPOS(dst)))) - #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) - #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) - #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) - #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) - #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) - #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out -// #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \ - (ISNEG(lop) && ISPOS(dst)) || \ - (ISPOS(rop) && ISPOS(dst))) - #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ - ((lop >= 0) && (rop) >= 0 && (dst < 0)))) - #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ - ((lop >= 0) && (rop) >= 0 && (dst < 0)))) - #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) - - #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ - (cpu->NFlag << 31) | \ - (cpu->ZFlag << 30) | \ - (cpu->CFlag << 29) | \ - (cpu->VFlag << 28) | \ - (cpu->TFlag << 5) - #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ - cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ - cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ - cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ - cpu->TFlag = (cpu->Cpsr >> 5) & 1; - - #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) - #define PC (cpu->Reg[15]) - #define CHECK_EXT_INT if (!cpu->NirqSig) { \ - if (!(cpu->Cpsr & 0x80)) { \ - goto END; \ - } \ - } - - - - //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); - arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj); + #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) + #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) + + #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) + #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) + #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) + #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) + #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) + #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) + + #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ + ((lop >= 0) && (rop) >= 0 && (dst < 0)))) + #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ + ((lop >= 0) && (rop) >= 0 && (dst < 0)))) + #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) + + #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ + (cpu->NFlag << 31) | \ + (cpu->ZFlag << 30) | \ + (cpu->CFlag << 29) | \ + (cpu->VFlag << 28) | \ + (cpu->TFlag << 5) + #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ + cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ + cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ + cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ + cpu->TFlag = (cpu->Cpsr >> 5) & 1; + + #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) + #define PC (cpu->Reg[15]) + #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END; + + arm_processor *cpu = state; // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback // to a clunky switch statement. #if defined __GNUC__ || defined __clang__ void *InstLabel[] = { - #define VFP_INTERPRETER_LABEL - #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" - #undef VFP_INTERPRETER_LABEL - &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, - &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, - &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, - &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, - &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, - &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, - &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, - &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, - &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, - &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST, - &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, - &&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 - }; -#endif - arm_inst * inst_base; - unsigned int lop, rop, dst; - unsigned int addr; - unsigned int phys_addr; - unsigned int last_pc = 0; - unsigned int num_instrs = 0; - fault_t fault; - static unsigned int last_physical_base = 0, last_logical_base = 0; - int ptr; - bool single_step = (cpu->NumInstrsToExecute == 1); - - LOAD_NZCVT; - DISPATCH: - { - if (!cpu->NirqSig) { - if (!(cpu->Cpsr & 0x80)) { - goto END; - } - } - - if (cpu->TFlag) { - cpu->Reg[15] &= 0xfffffffe; - } else - cpu->Reg[15] &= 0xfffffffc; -#if PROFILE - /* check next instruction address is valid. */ - last_pc = cpu->Reg[15]; + &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST, + &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST, + &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST, + &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST, + + &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, + &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, + &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, + &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, + &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, + &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, + &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, + &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, + &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, + &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST, + &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, + &&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 + }; #endif -#if USER_MODE_OPT - phys_addr = cpu->Reg[15]; -#else - { - if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) - phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); - else { - /* check next instruction address is valid. */ - fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); - if (fault) { - cpu->abortSig = true; - cpu->Aborted = ARMul_PrefetchAbortV; - cpu->AbortAddr = cpu->Reg[15]; - cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; - cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; - goto END; - } - last_logical_base = cpu->Reg[15] & 0xfffff000; - last_physical_base = phys_addr & 0xfffff000; - } - } -#if HYBRID_MODE - /* check if the native code of dyncom is available */ - //fast_map hash_map = core->dyncom_engine->fmap; - //void * pfunc = NULL; - //PFUNC(phys_addr); - //if(pfunc){ - if(is_translated_entry(core, phys_addr)){ - int rc = JIT_RETURN_NOERR; - //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]); - SAVE_NZCVT; -// resume_timing(); - rc = cpu_run(core); - LOAD_NZCVT; - //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]); - if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){ - /* keep the tflag same with the bit in CPSR */ - //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT); - //cpu->TFlag = cpu->Cpsr & (1 << 5); - //switch_mode(cpu, cpu->Cpsr & 0x1f); - //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]); - fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); - if (fault) { - cpu->abortSig = true; - cpu->Aborted = ARMul_PrefetchAbortV; - cpu->AbortAddr = cpu->Reg[15]; - cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; - cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; - goto END; - } - last_logical_base = cpu->Reg[15] & 0xfffff000; - last_physical_base = phys_addr & 0xfffff000; - core->current_page_phys = last_physical_base; - core->current_page_effec = last_logical_base; - //push_to_compiled(core, phys_addr); - } - else{ - if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){ - //DEBUG_LOG(ARM11, "\n\n###############In %s, fsr=0x%x, fault_addr=0x%x, pc=0x%x\n\n", __FUNCTION__, cpu->CP15[CP15(CP15_FAULT_STATUS)], cpu->CP15[CP15(CP15_FAULT_ADDRESS)], cpu->Reg[15]); - //core->Reg[15] -= get_instr_size(cpu_dyncom); - fill_tlb(cpu); - goto END; - } - if (cpu->syscallSig) { - goto END; - } - if (cpu->abortSig) { - cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0; - goto END; - } - if (!cpu->NirqSig) { - if (!(cpu->Cpsr & 0x80)) { - goto END; - } - } - - /* if regular trap */ - cpu->Reg[15] += GET_INST_SIZE(cpu); - /*uint32_t mode = cpu->Cpsr & 0x1f; - if ((mode != cpu->Mode) && (!is_user_mode(core))) { - switch_mode(cpu, mode); - return 1; - }*/ - - goto END; - } - //phys_addr = cpu->Reg[15]; - } - else{ - if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) - phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); - else { - /* check next instruction address is valid. */ - fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); - if (fault) { - cpu->abortSig = true; - cpu->Aborted = ARMul_PrefetchAbortV; - cpu->AbortAddr = cpu->Reg[15]; - cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; - cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; - goto END; - } - last_logical_base = cpu->Reg[15] & 0xfffff000; - last_physical_base = phys_addr & 0xfffff000; - } - } -#endif /* #if HYBRID_MODE */ -#endif /* #if USER_MODE_OPT */ - if (true){//if(is_fast_interp_code(core, phys_addr)){ - if (find_bb(phys_addr, ptr) == -1) - if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) - goto END; - } - else{ + arm_inst * inst_base; + unsigned int lop, rop, dst; + unsigned int addr; + unsigned int phys_addr; + unsigned int last_pc = 0; + unsigned int num_instrs = 0; + fault_t fault; + static unsigned int last_physical_base = 0, last_logical_base = 0; + int ptr; + bool single_step = (cpu->NumInstrsToExecute == 1); + + LOAD_NZCVT; + DISPATCH: + { + if (!cpu->NirqSig) { + if (!(cpu->Cpsr & 0x80)) { + goto END; + } + } + + if (cpu->TFlag) + cpu->Reg[15] &= 0xfffffffe; + else + cpu->Reg[15] &= 0xfffffffc; + + phys_addr = cpu->Reg[15]; + + if (find_bb(phys_addr, ptr) == -1) if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) - goto END; - } -#if PROFILE - resume_timing(); -#endif - inst_base = (arm_inst *)&inst_buf[ptr]; - GOTO_NEXT_INST; - } - ADC_INST: - { - INC_ICOUNTER; - adc_inst *inst_cream = (adc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - unsigned int sht_op = SHIFTER_OPERAND; - rop = SHIFTER_OPERAND + cpu->CFlag; - RD = dst = lop + rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); - UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(adc_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(adc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - ADD_INST: - { - INC_ICOUNTER; - add_inst *inst_cream = (add_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * GET_INST_SIZE(cpu); - } - rop = SHIFTER_OPERAND; - RD = dst = lop + rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr*/ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Cpsr & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG(dst, lop, rop); - UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(add_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(add_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - AND_INST: - { - INC_ICOUNTER; - and_inst *inst_cream = (and_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - rop = SHIFTER_OPERAND; - RD = dst = lop & rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr*/ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Cpsr & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; - //UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(and_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(and_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - BBL_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - bbl_inst *inst_cream = (bbl_inst *)inst_base->component; - if (inst_cream->L) { - LINK_RTN_ADDR; - } - SET_PC; - INC_PC(sizeof(bbl_inst)); - goto DISPATCH; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(bbl_inst)); - goto DISPATCH; - } - BIC_INST: - { - INC_ICOUNTER; - bic_inst *inst_cream = (bic_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * GET_INST_SIZE(cpu); - } - rop = SHIFTER_OPERAND; -// RD = dst = lop & (rop ^ 0xffffffff); - RD = dst = lop & (~rop); - if ((inst_cream->S) && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(bic_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(bic_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - BKPT_INST: - BLX_INST: - { - INC_ICOUNTER; - blx_inst *inst_cream = (blx_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int inst = inst_cream->inst; - if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { - //LINK_RTN_ADDR; - cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); - if(cpu->TFlag) - cpu->Reg[14] |= 0x1; - cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; - cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; - //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe; - //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1; - } else { - cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); - cpu->TFlag = 0x1; - int signed_int = inst_cream->val.signed_immed_24; - signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; - signed_int = signed_int << 2; - // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu) - cpu->Reg[15] = cpu->Reg[15] + 8 - + signed_int + (BIT(inst, 24) << 1); - //DEBUG_MSG; - } - INC_PC(sizeof(blx_inst)); - goto DISPATCH; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); -// INC_PC(sizeof(bx_inst)); - INC_PC(sizeof(blx_inst)); - goto DISPATCH; - } - BX_INST: - { - INC_ICOUNTER; - bx_inst *inst_cream = (bx_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - if (inst_cream->Rm == 15) - DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]); - cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; - cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; -// cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; - INC_PC(sizeof(bx_inst)); - goto DISPATCH; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); -// INC_PC(sizeof(bx_inst)); - INC_PC(sizeof(bx_inst)); - goto DISPATCH; - } - BXJ_INST: - CDP_INST: - { - INC_ICOUNTER; - cdp_inst *inst_cream = (cdp_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - /* FIXME, check if cp access allowed */ - #define CP_ACCESS_ALLOW 0 - if(CP_ACCESS_ALLOW){ - /* undefined instruction here */ - cpu->NumInstrsToExecute = 0; - return num_instrs; - } - ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); - unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); - if(cpab != ARMul_DONE){ - ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num); - //CITRA_IGNORE_EXIT(-1); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(cdp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - CLREX_INST: - { - INC_ICOUNTER; - remove_exclusive(cpu, 0); - cpu->exclusive_state = 0; - - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(clrex_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CLZ_INST: - { - INC_ICOUNTER; - clz_inst *inst_cream = (clz_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = clz(RM); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(clz_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CMN_INST: - { - INC_ICOUNTER; - cmn_inst *inst_cream = (cmn_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { -// DEBUG_LOG(ARM11, "RN is %x\n", RN); - lop = RN; - rop = SHIFTER_OPERAND; - dst = lop + rop; - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG(dst, lop, rop); - UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(cmn_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CMP_INST: - { -// DEBUG_LOG(ARM11, "cmp inst\n"); -// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { -// DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]); - cmp_inst *inst_cream = (cmp_inst *)inst_base->component; - lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * GET_INST_SIZE(cpu); - } - rop = SHIFTER_OPERAND; - dst = lop - rop; - - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); -// UPDATE_CFLAG(dst, lop, rop); - UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); -// UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); -// UPDATE_VFLAG_WITH_NOT(dst, lop, rop); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(cmp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CPS_INST: - { - INC_ICOUNTER; - cps_inst *inst_cream = (cps_inst *)inst_base->component; - uint32_t aif_val = 0; - uint32_t aif_mask = 0; - if (InAPrivilegedMode(cpu)) { - /* isInAPrivilegedMode */ - if (inst_cream->imod1) { - if (inst_cream->A) { - aif_val |= (inst_cream->imod0 << 8); - aif_mask |= 1 << 8; - } - if (inst_cream->I) { - aif_val |= (inst_cream->imod0 << 7); - aif_mask |= 1 << 7; - } - if (inst_cream->F) { - aif_val |= (inst_cream->imod0 << 6); - aif_mask |= 1 << 6; - } - aif_mask = ~aif_mask; - cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; - } - if (inst_cream->mmod) { - cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; - switch_mode(cpu, inst_cream->mode); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(cps_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CPY_INST: - { - INC_ICOUNTER; - mov_inst *inst_cream = (mov_inst *)inst_base->component; -// cpy_inst *inst_cream = (cpy_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = SHIFTER_OPERAND; -// RD = RM; - if ((inst_cream->Rd == 15)) { - INC_PC(sizeof(mov_inst)); - goto DISPATCH; - } - } -// DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]); - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mov_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - EOR_INST: - { - INC_ICOUNTER; - eor_inst *inst_cream = (eor_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * GET_INST_SIZE(cpu); - } - rop = SHIFTER_OPERAND; - RD = dst = lop ^ rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr*/ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; -// UPDATE_CFLAG(dst, lop, rop); -// UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(eor_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(eor_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDC_INST: - { - INC_ICOUNTER; - /* NOT IMPL */ - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDM_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - int i; - unsigned int ret; - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - unsigned int inst = inst_cream->inst; - if (BIT(inst, 22) && !BIT(inst, 15)) { -// DEBUG_MSG; - #if 1 - /* LDM (2) user */ - for (i = 0; i < 13; i++) { - if(BIT(inst, i)){ - #if 0 - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - #endif - fault = interpreter_read_memory(addr, phys_addr, ret, 32); - //if (fault) goto MMU_EXCEPTION; - cpu->Reg[i] = ret; - addr += 4; - if ((addr & 0xfff) == 0) { - fault = check_address_validity(cpu, addr, &phys_addr, 1); - } else { - phys_addr += 4; - } - } - } - if (BIT(inst, 13)) { - #if 0 - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - #endif - fault = interpreter_read_memory(addr, phys_addr, ret, 32); - //if (fault) goto MMU_EXCEPTION; - if (cpu->Mode == USER32MODE) - cpu->Reg[13] = ret; - else - cpu->Reg_usr[0] = ret; - addr += 4; - if ((addr & 0xfff) == 0) { - fault = check_address_validity(cpu, addr, &phys_addr, 1); - } else { - phys_addr += 4; - } - } - if (BIT(inst, 14)) { - #if 0 - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - #endif - fault = interpreter_read_memory(addr, phys_addr, ret, 32); - //if (fault) goto MMU_EXCEPTION; - if (cpu->Mode == USER32MODE) - cpu->Reg[14] = ret; - else - cpu->Reg_usr[1] = ret; - } - #endif - } else if (!BIT(inst, 22)) { - for( i = 0; i < 16; i ++ ){ - if(BIT(inst, i)){ - //bus_read(32, addr, &ret); - #if 0 - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - #endif - fault = interpreter_read_memory(addr, phys_addr, ret, 32); - if (fault) goto MMU_EXCEPTION; - /* For armv5t, should enter thumb when bits[0] is non-zero. */ - if(i == 15){ - cpu->TFlag = ret & 0x1; - ret &= 0xFFFFFFFE; - //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret); - } - - cpu->Reg[i] = ret; - addr += 4; - if ((addr & 0xfff) == 0) { - fault = check_address_validity(cpu, addr, &phys_addr, 1); - } else { - phys_addr += 4; - } - } - } - } else if (BIT(inst, 22) && BIT(inst, 15)) { - for( i = 0; i < 15; i ++ ){ - if(BIT(inst, i)){ - #if 0 - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - #endif - fault = interpreter_read_memory(addr, phys_addr, ret, 32); - //if (fault) goto MMU_EXCEPTION; - cpu->Reg[i] = ret; - addr += 4; - if ((addr & 0xfff) == 0) { - fault = check_address_validity(cpu, addr, &phys_addr, 1); - } else { - phys_addr += 4; - } - } - } - - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Cpsr & 0x1f); - LOAD_NZCVT; - } - #if 0 - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) { - goto MMU_EXCEPTION; - } - #endif - fault = interpreter_read_memory(addr, phys_addr, ret, 32); - if (fault) { - goto MMU_EXCEPTION; - } - cpu->Reg[15] = ret; - #if 0 - addr += 4; - phys_addr += 4; - #endif - } - if (BIT(inst, 15)) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SXTH_INST: - { - INC_ICOUNTER; - sxth_inst *inst_cream = (sxth_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); - if (BIT(operand2, 15)) { - operand2 |= 0xffff0000; - } else { - operand2 &= 0xffff; - } - RD = operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(sxth_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDR_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - //bus_read(32, addr, &value); - fault = interpreter_read_memory(addr, phys_addr, value, 32); - if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - else { - value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - } - if (BITS(inst_cream->inst, 12, 15) == 15) { - /* For armv5t, should enter thumb when bits[0] is non-zero. */ - cpu->TFlag = value & 0x1; - cpu->Reg[15] &= 0xFFFFFFFE; - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - //} - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRCOND_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if (CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - //bus_read(32, addr, &value); - fault = interpreter_read_memory(addr, phys_addr, value, 32); - if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - else { - value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + goto END; + + inst_base = (arm_inst *)&inst_buf[ptr]; + GOTO_NEXT_INST; + } + ADC_INST: + { + adc_inst *inst_cream = (adc_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + unsigned int sht_op = SHIFTER_OPERAND; + rop = SHIFTER_OPERAND + cpu->CFlag; + RD = dst = lop + rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); + UPDATE_VFLAG((int)dst, (int)lop, (int)rop); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(adc_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(adc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + ADD_INST: + { + add_inst *inst_cream = (add_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + if (inst_cream->Rn == 15) { + lop += 2 * GET_INST_SIZE(cpu); + } + rop = SHIFTER_OPERAND; + RD = dst = lop + rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Cpsr & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG(dst, lop, rop); + UPDATE_VFLAG((int)dst, (int)lop, (int)rop); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(add_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(add_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + AND_INST: + { + and_inst *inst_cream = (and_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + rop = SHIFTER_OPERAND; + RD = dst = lop & rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Cpsr & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(and_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(and_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + BBL_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + bbl_inst *inst_cream = (bbl_inst *)inst_base->component; + if (inst_cream->L) { + LINK_RTN_ADDR; + } + SET_PC; + INC_PC(sizeof(bbl_inst)); + goto DISPATCH; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(bbl_inst)); + goto DISPATCH; + } + BIC_INST: + { + bic_inst *inst_cream = (bic_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + if (inst_cream->Rn == 15) { + lop += 2 * GET_INST_SIZE(cpu); + } + rop = SHIFTER_OPERAND; + RD = dst = lop & (~rop); + if ((inst_cream->S) && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(bic_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(bic_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + BKPT_INST: + BLX_INST: + { + blx_inst *inst_cream = (blx_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int inst = inst_cream->inst; + if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { + cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); + if(cpu->TFlag) + cpu->Reg[14] |= 0x1; + cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; + cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; + } else { + cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); + cpu->TFlag = 0x1; + int signed_int = inst_cream->val.signed_immed_24; + signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; + signed_int = signed_int << 2; + cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1); + } + INC_PC(sizeof(blx_inst)); + goto DISPATCH; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(blx_inst)); + goto DISPATCH; + } + BX_INST: + { + bx_inst *inst_cream = (bx_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_cream->Rm == 15) + LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); + cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; + cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; + INC_PC(sizeof(bx_inst)); + goto DISPATCH; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(bx_inst)); + goto DISPATCH; + } + BXJ_INST: + CDP_INST: + { + cdp_inst *inst_cream = (cdp_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + // Undefined instruction here + cpu->NumInstrsToExecute = 0; + return num_instrs; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(cdp_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + CLREX_INST: + { + remove_exclusive(cpu, 0); + cpu->exclusive_state = 0; + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(clrex_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + CLZ_INST: + { + clz_inst *inst_cream = (clz_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + RD = clz(RM); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(clz_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + CMN_INST: + { + cmn_inst *inst_cream = (cmn_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + rop = SHIFTER_OPERAND; + dst = lop + rop; + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG(dst, lop, rop); + UPDATE_VFLAG((int)dst, (int)lop, (int)rop); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(cmn_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + CMP_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + cmp_inst *inst_cream = (cmp_inst *)inst_base->component; + lop = RN; + if (inst_cream->Rn == 15) { + lop += 2 * GET_INST_SIZE(cpu); + } + rop = SHIFTER_OPERAND; + dst = lop - rop; + + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); + UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(cmp_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + CPS_INST: + { + cps_inst *inst_cream = (cps_inst *)inst_base->component; + uint32_t aif_val = 0; + uint32_t aif_mask = 0; + if (InAPrivilegedMode(cpu)) { + if (inst_cream->imod1) { + if (inst_cream->A) { + aif_val |= (inst_cream->imod0 << 8); + aif_mask |= 1 << 8; + } + if (inst_cream->I) { + aif_val |= (inst_cream->imod0 << 7); + aif_mask |= 1 << 7; + } + if (inst_cream->F) { + aif_val |= (inst_cream->imod0 << 6); + aif_mask |= 1 << 6; + } + aif_mask = ~aif_mask; + cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; + } + if (inst_cream->mmod) { + cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; + switch_mode(cpu, inst_cream->mode); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(cps_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + CPY_INST: + { + mov_inst *inst_cream = (mov_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + RD = SHIFTER_OPERAND; + if ((inst_cream->Rd == 15)) { + INC_PC(sizeof(mov_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mov_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + EOR_INST: + { + eor_inst *inst_cream = (eor_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + if (inst_cream->Rn == 15) { + lop += 2 * GET_INST_SIZE(cpu); + } + rop = SHIFTER_OPERAND; + RD = dst = lop ^ rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(eor_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(eor_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDC_INST: + { + // Instruction not implemented + //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDM_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + int i; + unsigned int ret; + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) { + goto MMU_EXCEPTION; + } + unsigned int inst = inst_cream->inst; + if (BIT(inst, 22) && !BIT(inst, 15)) { + for (i = 0; i < 13; i++) { + if(BIT(inst, i)){ + fault = interpreter_read_memory(addr, phys_addr, ret, 32); + cpu->Reg[i] = ret; + addr += 4; + if ((addr & 0xfff) == 0) { + fault = check_address_validity(cpu, addr, &phys_addr, 1); + } else { + phys_addr += 4; + } + } + } + if (BIT(inst, 13)) { + fault = interpreter_read_memory(addr, phys_addr, ret, 32); + + if (cpu->Mode == USER32MODE) + cpu->Reg[13] = ret; + else + cpu->Reg_usr[0] = ret; + addr += 4; + if ((addr & 0xfff) == 0) { + fault = check_address_validity(cpu, addr, &phys_addr, 1); + } else { + phys_addr += 4; + } + } + if (BIT(inst, 14)) { + fault = interpreter_read_memory(addr, phys_addr, ret, 32); + + if (cpu->Mode == USER32MODE) + cpu->Reg[14] = ret; + else + cpu->Reg_usr[1] = ret; + } + } else if (!BIT(inst, 22)) { + for( i = 0; i < 16; i ++ ){ + if(BIT(inst, i)){ + fault = interpreter_read_memory(addr, phys_addr, ret, 32); + if (fault) goto MMU_EXCEPTION; + + // For armv5t, should enter thumb when bits[0] is non-zero. + if(i == 15){ + cpu->TFlag = ret & 0x1; + ret &= 0xFFFFFFFE; } - if (BITS(inst_cream->inst, 12, 15) == 15) { - /* For armv5t, should enter thumb when bits[0] is non-zero. */ - cpu->TFlag = value & 0x1; - cpu->Reg[15] &= 0xFFFFFFFE; - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTH_INST: - { - INC_ICOUNTER; - uxth_inst *inst_cream = (uxth_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xffff; - RD = operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(uxth_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTAH_INST: - { - INC_ICOUNTER; - uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xffff; - RD = RN + operand2; - if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { - DEBUG_LOG(ARM11, "in line %d\n", __LINE__); - CITRA_IGNORE_EXIT(-1); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(uxtah_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRB_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - //bus_read(8, addr, &value); - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRBT_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRD_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */ - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - uint32_t rear_phys_addr; - fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); - if(fault){ - ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n"); - CITRA_IGNORE_EXIT(-1); - goto MMU_EXCEPTION; - } - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; - /* No dispatch since this operation should not modify R15 */ - } - cpu->Reg[15] += 4; - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - LDREX_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - - add_exclusive_addr(cpu, phys_addr); - cpu->exclusive_state = 1; - - //bus_read(32, addr, &value); - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDREXB_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - - add_exclusive_addr(cpu, phys_addr); - cpu->exclusive_state = 1; - - //bus_read(8, addr, &value); - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRH_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value = 0; - fault = interpreter_read_memory(addr, phys_addr, value, 16); -// fault = interpreter_read_memory(addr, value, 32); - if (fault) goto MMU_EXCEPTION; - //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) { - // value = 0xffffffff; - //} - //bus_read(16, addr, &value); -// cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff; - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRSB_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; -// DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr); - fault = interpreter_read_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - //bus_read(8, addr, &value); - if (BIT(value, 7)) { - value |= 0xffffff00; - } - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRSH_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 16); - if (fault) goto MMU_EXCEPTION; - //bus_read(16, addr, &value); - if (BIT(value, 15)) { - value |= 0xffff0000; - } - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRT_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - - if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - else - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; - - if (BITS(inst_cream->inst, 12, 15) == 15) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MCR_INST: - { - INC_ICOUNTER; - /* NOT IMPL */ - mcr_inst *inst_cream = (mcr_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int inst = inst_cream->inst; - if (inst_cream->Rd == 15) { - DEBUG_MSG; - } else { - if (inst_cream->cp_num == 15) { - if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { - //LET(RD, CONST(0x0007b000)); - //LET(RD, CONST(0x410FB760)); - //LET(CP15_MAIN_ID, R(RD)); - CP15_REG(CP15_MAIN_ID) = RD; - } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { - //LET(RD, R(CP15_CONTROL)); - CP15_REG(CP15_AUXILIARY_CONTROL) = RD; - } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { - //LET(RD, R(CP15_CONTROL)); - CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; - } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { - //LET(CP15_CONTROL, R(RD)); - CP15_REG(CP15_CONTROL) = RD; - } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { - //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD)); - CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; - } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { - //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD)); - CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; - } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { - //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD)); - CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; - } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { - //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD)); - CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; - } else if(CRn == MMU_CACHE_OPS){ - //SKYEYE_WARNING("cache operation have not implemented.\n"); - } else if(CRn == MMU_TLB_OPS){ - switch (CRm) { - case 5: /* ITLB */ - switch(OPCODE_2){ - case 0: /* invalidate all */ - //invalidate_all_tlb(state); - DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n"); - //remove_tlb(INSN_TLB); - //erase_all(core, INSN_TLB); - break; - case 1: /* invalidate by MVA */ - //invalidate_by_mva(state, value); - //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n"); - //remove_tlb_by_mva(RD, INSN_TLB); - //erase_by_mva(core, RD, INSN_TLB); - break; - case 2: /* invalidate by asid */ - //invalidate_by_asid(state, value); - //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n"); - //erase_by_asid(core, RD, INSN_TLB); - break; - default: - break; - } - - break; - case 6: /* DTLB */ - switch(OPCODE_2){ - case 0: /* invalidate all */ - //invalidate_all_tlb(state); - //remove_tlb(DATA_TLB); - //erase_all(core, DATA_TLB); - DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n"); - break; - case 1: /* invalidate by MVA */ - //invalidate_by_mva(state, value); - //remove_tlb_by_mva(RD, DATA_TLB); - //erase_by_mva(core, RD, DATA_TLB); - //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n"); - break; - case 2: /* invalidate by asid */ - //invalidate_by_asid(state, value); - //remove_tlb_by_asid(RD, DATA_TLB); - //erase_by_asid(core, RD, DATA_TLB); - //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n"); - break; - default: - break; - } - break; - case 7: /* UNIFILED TLB */ - switch(OPCODE_2){ - case 0: /* invalidate all */ - //invalidate_all_tlb(state); - //erase_all(core, INSN_TLB); - //erase_all(core, DATA_TLB); - //remove_tlb(DATA_TLB); - //remove_tlb(INSN_TLB); - //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n"); - break; - case 1: /* invalidate by MVA */ - //invalidate_by_mva(state, value); - //erase_by_mva(core, RD, DATA_TLB); - //erase_by_mva(core, RD, INSN_TLB); - DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n"); - break; - case 2: /* invalidate by asid */ - //invalidate_by_asid(state, value); - //erase_by_asid(core, RD, DATA_TLB); - //erase_by_asid(core, RD, INSN_TLB); - DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n"); - break; - default: - break; - } - break; - default: - break; - } - } else if(CRn == MMU_PID){ - if(OPCODE_2 == 0) - CP15_REG(CP15_PID) = RD; - else if(OPCODE_2 == 1) - CP15_REG(CP15_CONTEXT_ID) = RD; - else if(OPCODE_2 == 3){ - CP15_REG(CP15_THREAD_URO) = RD; - } - else{ - printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn); - } - - } else { - DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); - } - } - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mcr_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MCRR_INST: - MLA_INST: - { - INC_ICOUNTER; - mla_inst *inst_cream = (mla_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - uint64_t rm = RM; - uint64_t rs = RS; - uint64_t rn = RN; - if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { - DEBUG_LOG(ARM11, "in __line__\n", __LINE__); - CITRA_IGNORE_EXIT(-1); - } -// RD = dst = RM * RS + RN; - RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); - if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mla_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mla_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MOV_INST: - { -// DEBUG_LOG(ARM11, "mov inst\n"); -// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); -// debug_function(cpu); -// cpu->icount ++; - INC_ICOUNTER; - mov_inst *inst_cream = (mov_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = dst = SHIFTER_OPERAND; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mov_inst)); - goto DISPATCH; - } -// return; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mov_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MRC_INST: - { - INC_ICOUNTER; - /* NOT IMPL */ - mrc_inst *inst_cream = (mrc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int inst = inst_cream->inst; - if (inst_cream->Rd == 15) { - DEBUG_MSG; - } - if (inst_cream->inst == 0xeef04a10) { - /* undefined instruction fmrx */ - RD = 0x20000000; - CITRA_IGNORE_EXIT(-1); - goto END; - } else { - if (inst_cream->cp_num == 15) { - if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { - //LET(RD, CONST(0x0007b000)); - //LET(RD, CONST(0x410FB760)); - //LET(RD, R(CP15_MAIN_ID)); - RD = cpu->CP15[CP15(CP15_MAIN_ID)]; - } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { - //LET(RD, R(CP15_CONTROL)); - RD = cpu->CP15[CP15(CP15_CONTROL)]; - } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { - //LET(RD, R(CP15_CONTROL)); - RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; - } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { - //LET(RD, R(CP15_CONTROL)); - RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; - } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { - //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL)); - RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; - } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { - //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0)); - RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; - } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { - //LET(RD, R(CP15_FAULT_STATUS)); - RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; - } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { - //LET(RD, R(CP15_FAULT_ADDRESS)); - RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; - } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { - //LET(RD, R(CP15_CACHE_TYPE)); - RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; - } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { - //LET(RD, R(CP15_INSTR_FAULT_STATUS)); - RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; - } else if (CRn == 13) { - if(OPCODE_2 == 0) - RD = CP15_REG(CP15_PID); - else if(OPCODE_2 == 1) - RD = CP15_REG(CP15_CONTEXT_ID); - else if(OPCODE_2 == 3){ - RD = Memory::KERNEL_MEMORY_VADDR; - } - else{ - printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn); - } - } - else { - DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); - } - } - //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mrc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MRRC_INST: - MRS_INST: - { - INC_ICOUNTER; - mrs_inst *inst_cream = (mrs_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - if (inst_cream->R) { - RD = cpu->Spsr_copy; - } else { - SAVE_NZCVT; - RD = cpu->Cpsr; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mrs_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MSR_INST: - { - INC_ICOUNTER; - msr_inst *inst_cream = (msr_inst *)inst_base->component; - const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; - unsigned int inst = inst_cream->inst; - unsigned int operand; - - if (BIT(inst, 25)) { - int rot_imm = BITS(inst, 8, 11) * 2; - //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm)); - operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); - } else { - //operand = R(RM); - operand = cpu->Reg[BITS(inst, 0, 3)]; - } - uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) - | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); - uint32_t mask; - if (!inst_cream->R) { - if (InAPrivilegedMode(cpu)) { - if ((operand & StateMask) != 0) { - /* UNPREDICTABLE */ - DEBUG_MSG; - } else - mask = byte_mask & (UserMask | PrivMask); - } else { - mask = byte_mask & UserMask; - } - //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); - SAVE_NZCVT; - - cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); - switch_mode(cpu, cpu->Cpsr & 0x1f); - LOAD_NZCVT; - } else { - if (CurrentModeHasSPSR) { - mask = byte_mask & (UserMask | PrivMask | StateMask); - //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); - cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(msr_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MUL_INST: - { - INC_ICOUNTER; - mul_inst *inst_cream = (mul_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { -// RD = dst = SHIFTER_OPERAND; - uint64_t rm = RM; - uint64_t rs = RS; - RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); - if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mul_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mul_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MVN_INST: - { - INC_ICOUNTER; - mvn_inst *inst_cream = (mvn_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { -// RD = dst = (SHIFTER_OPERAND ^ 0xffffffff); - RD = dst = ~SHIFTER_OPERAND; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mvn_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(mvn_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - ORR_INST: - { - INC_ICOUNTER; - orr_inst *inst_cream = (orr_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - rop = SHIFTER_OPERAND; -// DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]); - RD = dst = lop | rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr*/ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; -// UPDATE_CFLAG(dst, lop, rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(orr_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(orr_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - PKHBT_INST: - PKHTB_INST: - PLD_INST: - { - INC_ICOUNTER; - /* NOT IMPL */ - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(stc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - QADD_INST: - QADD16_INST: - QADD8_INST: - QADDSUBX_INST: - QDADD_INST: - QDSUB_INST: - QSUB_INST: - QSUB16_INST: - QSUB8_INST: - QSUBADDX_INST: - REV_INST: - { - INC_ICOUNTER; - 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) { - DEBUG_LOG(ARM11, "in line %d\n", __LINE__); - CITRA_IGNORE_EXIT(-1); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(rev_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - REV16_INST: - { - INC_ICOUNTER; - 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); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(rev_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - REVSH_INST: - RFE_INST: - RSB_INST: - { - INC_ICOUNTER; - rsb_inst *inst_cream = (rsb_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - rop = RN; - lop = SHIFTER_OPERAND; - if (inst_cream->Rn == 15) { - rop += 2 * GET_INST_SIZE(cpu);; - } - RD = dst = lop - rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); -// UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(rsb_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(rsb_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - RSC_INST: - { - INC_ICOUNTER; - rsc_inst *inst_cream = (rsc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - //lop = RN + !cpu->CFlag; - //rop = SHIFTER_OPERAND; - //RD = dst = rop - lop; - lop = RN; - rop = SHIFTER_OPERAND; - RD = dst = rop - lop - !cpu->CFlag; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); -// UPDATE_CFLAG(dst, lop, rop); -// UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); - UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); -// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); - UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(rsc_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(rsc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SADD16_INST: - SADD8_INST: - SADDSUBX_INST: - SBC_INST: - { - INC_ICOUNTER; - sbc_inst *inst_cream = (sbc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = SHIFTER_OPERAND + !cpu->CFlag; - rop = RN; - RD = dst = rop - lop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); -// UPDATE_CFLAG(dst, lop, rop); - //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); - //rop = rop - !cpu->CFlag; - if(rop >= !cpu->CFlag) - UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); - else - UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); -// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); - UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(sbc_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(sbc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SEL_INST: - SETEND_INST: - SHADD16_INST: - SHADD8_INST: - SHADDSUBX_INST: - SHSUB16_INST: - SHSUB8_INST: - SHSUBADDX_INST: - SMLA_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - smla_inst *inst_cream = (smla_inst *)inst_base->component; - int32_t operand1, operand2; - if (inst_cream->x == 0) - operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); - else - operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); - - if (inst_cream->y == 0) - operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); - else - operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); - RD = operand1 * operand2 + RN; - //FIXME: UPDATE Q FLAGS - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(smla_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SMLAD_INST: - { - INC_ICOUNTER; - 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]; - /* 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; - half_rn = rn & 0xFFFF; - half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; - - half_operand2 = operand2 & 0xFFFF; - half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; - - long long int product1 = half_rn * half_operand2; - - half_rn = (rn & 0xFFFF0000) >> 16; - half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; - - half_operand2 = (operand2 & 0xFFFF0000) >> 16; - half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; - - long long int product2 = half_rn * half_operand2; - - 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; - /* FIXME , should check Signed overflow */ - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(umlal_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - SMLAL_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; - long long int rm = RM; - long long int rs = RS; - if (BIT(rm, 31)) { - rm |= 0xffffffff00000000LL; - } - if (BIT(rs, 31)) { - rs |= 0xffffffff00000000LL; - } - long long int rst = rm * rs; - long long int rdhi32 = RDHI; - long long int hilo = (rdhi32 << 32) + RDLO; - rst += hilo; - RDLO = BITS(rst, 0, 31); - RDHI = BITS(rst, 32, 63); - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(umlal_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SMLALXY_INST: - SMLALD_INST: - SMLAW_INST: - SMLSD_INST: - SMLSLD_INST: - SMMLA_INST: - SMMLS_INST: - SMMUL_INST: - SMUAD_INST: - SMUL_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - smul_inst *inst_cream = (smul_inst *)inst_base->component; - uint32_t operand1, operand2; - if (inst_cream->x == 0) - operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); - else - operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); - - if (inst_cream->y == 0) - operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); - else - operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); - RD = operand1 * operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(smul_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SMULL_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umull_inst *inst_cream = (umull_inst *)inst_base->component; -// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); - int64_t rm = RM; - int64_t rs = RS; - if (BIT(rm, 31)) { - rm |= 0xffffffff00000000LL; - } - if (BIT(rs, 31)) { - rs |= 0xffffffff00000000LL; - } - int64_t rst = rm * rs; - RDHI = BITS(rst, 32, 63); - RDLO = BITS(rst, 0, 31); - - - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(umull_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SMULW_INST: - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - smlad_inst *inst_cream = (smlad_inst *)inst_base->component; -// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); - int64_t rm = RM; - int64_t rn = RN; - if (inst_cream->m) - rm = BITS(rm,16 , 31); - else - rm = BITS(rm,0 , 15); - int64_t rst = rm * rn; - RD = BITS(rst, 16, 47); - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(smlad_inst)); - FETCH_INST; - GOTO_NEXT_INST; - - SMUSD_INST: - SRS_INST: - SSAT_INST: - SSAT16_INST: - SSUB16_INST: - SSUB8_INST: - SSUBADDX_INST: - STC_INST: - { - INC_ICOUNTER; - /* NOT IMPL */ - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(stc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STM_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - unsigned int inst = inst_cream->inst; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - int i; - unsigned int Rn = BITS(inst, 16, 19); - unsigned int old_RN = cpu->Reg[Rn]; - - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - if (BIT(inst_cream->inst, 22) == 1) { -// DEBUG_MSG; - #if 1 - for (i = 0; i < 13; i++) { - if(BIT(inst_cream->inst, i)){ - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); - if (fault) goto MMU_EXCEPTION; - addr += 4; - phys_addr += 4; - } - } - if (BIT(inst_cream->inst, 13)) { - if (cpu->Mode == USER32MODE) { - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); - if (fault) goto MMU_EXCEPTION; - addr += 4; - phys_addr += 4; - } else { - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); - if (fault) goto MMU_EXCEPTION; - addr += 4; - phys_addr += 4; - } - } - if (BIT(inst_cream->inst, 14)) { - if (cpu->Mode == USER32MODE) { - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); - if (fault) goto MMU_EXCEPTION; - addr += 4; - phys_addr += 4; - } else { - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); - if (fault) goto MMU_EXCEPTION; - addr += 4; - phys_addr += 4; - } - } - if (BIT(inst_cream->inst, 15)) { - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); - if (fault) goto MMU_EXCEPTION; - } - #endif - } else { - for( i = 0; i < 15; i ++ ){ - if(BIT(inst_cream->inst, i)){ - //arch_write_memory(cpu, bb, Addr, R(i), 32); - //bus_write(32, addr, cpu->Reg[i]); - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - if(i == Rn) - fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); - else - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); - if (fault) goto MMU_EXCEPTION; - addr += 4; - phys_addr += 4; - //Addr = ADD(Addr, CONST(4)); - } - } - - /* check pc reg*/ - if(BIT(inst_cream->inst, i)){ - //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32); - //bus_write(32, addr, cpu->Reg[i] + 8); - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) { - goto MMU_EXCEPTION; - } - fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); - if (fault) goto MMU_EXCEPTION; - } - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SXTB_INST: - { - INC_ICOUNTER; - sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - if (inst_cream->Rm == 15) { - DEBUG_LOG(ARM11, "line is %d\n", __LINE__); - CITRA_IGNORE_EXIT(-1); - } - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); - if (BIT(operand2, 7)) { - operand2 |= 0xffffff00; - } else - operand2 &= 0xff; - RD = operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(sxtb_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STR_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; - //bus_write(32, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTB_INST: - { - INC_ICOUNTER; - uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xff; - RD = operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(uxtb_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTAB_INST: - { - INC_ICOUNTER; - uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xff; - RD = RN + operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(uxtab_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRB_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; - //bus_write(8, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRBT_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; - //bus_write(8, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - //if (BITS(inst_cream->inst, 12, 15) == 15) - // goto DISPATCH; - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRD_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - uint32_t rear_phys_addr; - fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); + cpu->Reg[i] = ret; + addr += 4; + if ((addr & 0xfff) == 0) { + fault = check_address_validity(cpu, addr, &phys_addr, 1); + } else { + phys_addr += 4; + } + } + } + } else if (BIT(inst, 22) && BIT(inst, 15)) { + for( i = 0; i < 15; i ++ ){ + if(BIT(inst, i)){ + fault = interpreter_read_memory(addr, phys_addr, ret, 32); + cpu->Reg[i] = ret; + addr += 4; + if ((addr & 0xfff) == 0) { + fault = check_address_validity(cpu, addr, &phys_addr, 1); + } else { + phys_addr += 4; + } + } + } + + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Cpsr & 0x1f); + LOAD_NZCVT; + } + + fault = interpreter_read_memory(addr, phys_addr, ret, 32); + if (fault) { + goto MMU_EXCEPTION; + } + cpu->Reg[15] = ret; + } + if (BIT(inst, 15)) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SXTH_INST: + { + sxth_inst *inst_cream = (sxth_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); + if (BIT(operand2, 15)) { + operand2 |= 0xffff0000; + } else { + operand2 &= 0xffff; + } + RD = operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(sxth_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDR_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 32); + if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + else { + value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + } + if (BITS(inst_cream->inst, 12, 15) == 15) { + // For armv5t, should enter thumb when bits[0] is non-zero. + cpu->TFlag = value & 0x1; + cpu->Reg[15] &= 0xFFFFFFFE; + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + //} + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRCOND_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if (CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 32); + if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + else { + value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + } + + if (BITS(inst_cream->inst, 12, 15) == 15) { + // For armv5t, should enter thumb when bits[0] is non-zero. + cpu->TFlag = value & 0x1; + cpu->Reg[15] &= 0xFFFFFFFE; + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UXTH_INST: + { + uxth_inst *inst_cream = (uxth_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) + & 0xffff; + RD = operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(uxth_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UXTAH_INST: + { + uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) + & 0xffff; + RD = RN + operand2; + if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { + LOG_ERROR(Core_ARM11, "invalid operands for UXTAH"); + CITRA_IGNORE_EXIT(-1); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(uxtah_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRB_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + if (BITS(inst_cream->inst, 12, 15) == 15) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRBT_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + if (BITS(inst_cream->inst, 12, 15) == 15) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRD_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + uint32_t rear_phys_addr; + fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); + if(fault){ + LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr\n"); + CITRA_IGNORE_EXIT(-1); + goto MMU_EXCEPTION; + } + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; + + // No dispatch since this operation should not modify R15 + } + cpu->Reg[15] += 4; + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + LDREX_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; + fault = check_address_validity(cpu, addr, &phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + + add_exclusive_addr(cpu, phys_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)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDREXB_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; + fault = check_address_validity(cpu, addr, &phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + + add_exclusive_addr(cpu, phys_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)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRH_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value = 0; + fault = interpreter_read_memory(addr, phys_addr, value, 16); + if (fault) goto MMU_EXCEPTION; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + if (BITS(inst_cream->inst, 12, 15) == 15) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRSB_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + if (BIT(value, 7)) { + value |= 0xffffff00; + } + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + if (BITS(inst_cream->inst, 12, 15) == 15) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRSH_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 16); + if (fault) goto MMU_EXCEPTION; + if (BIT(value, 15)) { + value |= 0xffff0000; + } + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + if (BITS(inst_cream->inst, 12, 15) == 15) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + LDRT_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + + if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + else + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; + + if (BITS(inst_cream->inst, 12, 15) == 15) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MCR_INST: + { + mcr_inst *inst_cream = (mcr_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int inst = inst_cream->inst; + if (inst_cream->Rd == 15) { + DEBUG_MSG; + } else { + if (inst_cream->cp_num == 15) { + if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { + CP15_REG(CP15_MAIN_ID) = RD; + } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { + CP15_REG(CP15_AUXILIARY_CONTROL) = RD; + } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { + CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; + } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { + CP15_REG(CP15_CONTROL) = RD; + } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { + CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; + } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { + CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; + } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { + CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; + } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { + CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; + } else if(CRn == MMU_CACHE_OPS){ + //LOG_WARNING(Core_ARM11, "cache operations have not implemented."); + } else if(CRn == MMU_TLB_OPS){ + switch (CRm) { + case 5: // ITLB + switch(OPCODE_2) { + case 0: // Invalidate all + LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all"); + break; + case 1: // Invalidate by MVA + LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by mva"); + break; + case 2: // Invalidate by asid + LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by asid"); + break; + default: + break; + } + + break; + case 6: // DTLB + switch(OPCODE_2){ + case 0: // Invalidate all + LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all"); + break; + case 1: // Invalidate by MVA + LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by mva"); + break; + case 2: // Invalidate by asid + LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by asid"); + break; + default: + break; + } + break; + case 7: // UNIFILED TLB + switch(OPCODE_2){ + case 0: // invalidate all + LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate all"); + break; + case 1: // Invalidate by MVA + LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva"); + break; + case 2: // Invalidate by asid + LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid"); + break; + default: + break; + } + break; + default: + break; + } + } else if(CRn == MMU_PID) { + if(OPCODE_2 == 0) + CP15_REG(CP15_PID) = RD; + else if(OPCODE_2 == 1) + CP15_REG(CP15_CONTEXT_ID) = RD; + else if(OPCODE_2 == 3) { + CP15_REG(CP15_THREAD_URO) = RD; + } else { + LOG_ERROR(Core_ARM11, "mmu_mcr wrote UNKNOWN - reg %d", CRn); + } + } else { + LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2); + } + } + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mcr_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MCRR_INST: + MLA_INST: + { + mla_inst *inst_cream = (mla_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + uint64_t rm = RM; + uint64_t rs = RS; + uint64_t rn = RN; + if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { + LOG_ERROR(Core_ARM11, "invalid operands for MLA"); + CITRA_IGNORE_EXIT(-1); + } + RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); + if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mla_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mla_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MOV_INST: + { + mov_inst *inst_cream = (mov_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + RD = dst = SHIFTER_OPERAND; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mov_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mov_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MRC_INST: + { + mrc_inst *inst_cream = (mrc_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int inst = inst_cream->inst; + if (inst_cream->Rd == 15) { + DEBUG_MSG; + } + if (inst_cream->inst == 0xeef04a10) { + // Undefined instruction fmrx + RD = 0x20000000; + CITRA_IGNORE_EXIT(-1); + goto END; + } else { + if (inst_cream->cp_num == 15) { + if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { + RD = cpu->CP15[CP15(CP15_MAIN_ID)]; + } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { + RD = cpu->CP15[CP15(CP15_CONTROL)]; + } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { + RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; + } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { + RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; + } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { + RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; + } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { + RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; + } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { + RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; + } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { + RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; + } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { + RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; + } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { + RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; + } else if (CRn == 13) { + if(OPCODE_2 == 0) + RD = CP15_REG(CP15_PID); + else if(OPCODE_2 == 1) + RD = CP15_REG(CP15_CONTEXT_ID); + else if(OPCODE_2 == 3) { + RD = Memory::KERNEL_MEMORY_VADDR; + } else { + LOG_ERROR(Core_ARM11, "mmu_mrr wrote UNKNOWN - reg %d", CRn); + } + } else { + LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2); + } + } + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mrc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MRRC_INST: + MRS_INST: + { + mrs_inst *inst_cream = (mrs_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_cream->R) { + RD = cpu->Spsr_copy; + } else { + SAVE_NZCVT; + RD = cpu->Cpsr; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mrs_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MSR_INST: + { + msr_inst *inst_cream = (msr_inst *)inst_base->component; + const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; + unsigned int inst = inst_cream->inst; + unsigned int operand; + + if (BIT(inst, 25)) { + int rot_imm = BITS(inst, 8, 11) * 2; + operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); + } else { + operand = cpu->Reg[BITS(inst, 0, 3)]; + } + uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) + | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); + uint32_t mask; + if (!inst_cream->R) { + if (InAPrivilegedMode(cpu)) { + if ((operand & StateMask) != 0) { + /// UNPREDICTABLE + DEBUG_MSG; + } else + mask = byte_mask & (UserMask | PrivMask); + } else { + mask = byte_mask & UserMask; + } + SAVE_NZCVT; + + cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); + switch_mode(cpu, cpu->Cpsr & 0x1f); + LOAD_NZCVT; + } else { + if (CurrentModeHasSPSR) { + mask = byte_mask & (UserMask | PrivMask | StateMask); + cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(msr_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MUL_INST: + { + mul_inst *inst_cream = (mul_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + uint64_t rm = RM; + uint64_t rs = RS; + RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); + if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mul_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mul_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + MVN_INST: + { + mvn_inst *inst_cream = (mvn_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + RD = dst = ~SHIFTER_OPERAND; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mvn_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(mvn_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + ORR_INST: + { + orr_inst *inst_cream = (orr_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + rop = SHIFTER_OPERAND; + RD = dst = lop | rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(orr_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(orr_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + PKHBT_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + pkh_inst *inst_cream = (pkh_inst *)inst_base->component; + RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(pkh_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + PKHTB_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + pkh_inst *inst_cream = (pkh_inst *)inst_base->component; + int shift_imm = inst_cream->imm ? inst_cream->imm : 31; + RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(pkh_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + PLD_INST: + { + // Instruction not implemented + //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(stc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + QADD_INST: + QADD8_INST: + QADD16_INST: + QADDSUBX_INST: + QSUB8_INST: + QSUB16_INST: + QSUBADDX_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + const u16 rm_lo = (RM & 0xFFFF); + const u16 rm_hi = ((RM >> 16) & 0xFFFF); + const u16 rn_lo = (RN & 0xFFFF); + const u16 rn_hi = ((RN >> 16) & 0xFFFF); + const u8 op2 = inst_cream->op2; + + u16 lo_result = 0; + u16 hi_result = 0; + + // QADD16 + if (op2 == 0x00) { + lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); + hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); + } + // QASX + else if (op2 == 0x01) { + lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); + hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); + } + // QSAX + else if (op2 == 0x02) { + lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); + hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); + } + // QSUB16 + else if (op2 == 0x03) { + lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); + hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); + } + // QADD8 + else if (op2 == 0x04) { + lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | + ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; + hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | + ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; + } + // QSUB8 + else if (op2 == 0x07) { + lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | + ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; + hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | + ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; + } + + RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + 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: + { + 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); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(rev_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + REVSH_INST: + RFE_INST: + RSB_INST: + { + rsb_inst *inst_cream = (rsb_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + rop = RN; + lop = SHIFTER_OPERAND; + if (inst_cream->Rn == 15) { + rop += 2 * GET_INST_SIZE(cpu);; + } + RD = dst = lop - rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); + UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(rsb_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(rsb_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + RSC_INST: + { + rsc_inst *inst_cream = (rsc_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + rop = SHIFTER_OPERAND; + RD = dst = rop - lop - !cpu->CFlag; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); + UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(rsc_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(rsc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SADD8_INST: + SADD16_INST: + SADDSUBX_INST: + SSUBADDX_INST: + SSUB16_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + + const s16 rn_lo = (RN & 0xFFFF); + const s16 rn_hi = ((RN >> 16) & 0xFFFF); + const s16 rm_lo = (RM & 0xFFFF); + const s16 rm_hi = ((RM >> 16) & 0xFFFF); + + s32 lo_result = 0; + s32 hi_result = 0; + + // SADD16 + if (inst_cream->op2 == 0x00) { + lo_result = (rn_lo + rm_lo); + hi_result = (rn_hi + rm_hi); + } + // SASX + else if (inst_cream->op2 == 0x01) { + lo_result = (rn_lo - rm_hi); + hi_result = (rn_hi + rm_lo); + } + // SSAX + else if (inst_cream->op2 == 0x02) { + lo_result = (rn_lo + rm_hi); + hi_result = (rn_hi - rm_lo); + } + // SSUB16 + else if (inst_cream->op2 == 0x03) { + lo_result = (rn_lo - rm_lo); + hi_result = (rn_hi - rm_hi); + } + + RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); + + if (lo_result >= 0) { + cpu->Cpsr |= (1 << 16); + cpu->Cpsr |= (1 << 17); + } else { + cpu->Cpsr &= ~(1 << 16); + cpu->Cpsr &= ~(1 << 17); + } + + if (hi_result >= 0) { + cpu->Cpsr |= (1 << 18); + cpu->Cpsr |= (1 << 19); + } else { + cpu->Cpsr &= ~(1 << 18); + cpu->Cpsr &= ~(1 << 19); + } + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SBC_INST: + { + sbc_inst *inst_cream = (sbc_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = SHIFTER_OPERAND + !cpu->CFlag; + rop = RN; + RD = dst = rop - lop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + + if(rop >= !cpu->CFlag) + UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); + else + UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); + + UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(sbc_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(sbc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SEL_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + + const u32 to = RM; + const u32 from = RN; + const u32 cpsr = cpu->Cpsr; + + u32 result; + if (cpsr & (1 << 16)) + result = from & 0xff; + else + result = to & 0xff; + + if (cpsr & (1 << 17)) + result |= from & 0x0000ff00; + else + result |= to & 0x0000ff00; + + if (cpsr & (1 << 18)) + result |= from & 0x00ff0000; + else + result |= to & 0x00ff0000; + + if (cpsr & (1 << 19)) + result |= from & 0xff000000; + else + result |= to & 0xff000000; + + RD = result; + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SETEND_INST: + SHADD16_INST: + SHADD8_INST: + SHADDSUBX_INST: + SHSUB16_INST: + SHSUB8_INST: + SHSUBADDX_INST: + SMLA_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + smla_inst *inst_cream = (smla_inst *)inst_base->component; + int32_t operand1, operand2; + if (inst_cream->x == 0) + operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); + else + operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); + + if (inst_cream->y == 0) + operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); + else + operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); + RD = operand1 * operand2 + RN; + + // TODO: FIXME: UPDATE Q FLAGS + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smla_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SMLAD_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]; + + // 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; + + half_rn = rn & 0xFFFF; + half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; + + half_operand2 = operand2 & 0xFFFF; + half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; + + long long int product1 = half_rn * half_operand2; + + half_rn = (rn & 0xFFFF0000) >> 16; + half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; + + half_operand2 = (operand2 & 0xFFFF0000) >> 16; + half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; + + long long int product2 = half_rn * half_operand2; + + 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; + + // TODO: FIXME should check Signed overflow + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(umlal_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SMLAL_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + umlal_inst *inst_cream = (umlal_inst *)inst_base->component; + long long int rm = RM; + long long int rs = RS; + if (BIT(rm, 31)) { + rm |= 0xffffffff00000000LL; + } + if (BIT(rs, 31)) { + rs |= 0xffffffff00000000LL; + } + long long int rst = rm * rs; + long long int rdhi32 = RDHI; + long long int hilo = (rdhi32 << 32) + RDLO; + rst += hilo; + RDLO = BITS(rst, 0, 31); + RDHI = BITS(rst, 32, 63); + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(umlal_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SMLALXY_INST: + SMLALD_INST: + SMLAW_INST: + SMLSD_INST: + SMLSLD_INST: + SMMLA_INST: + SMMLS_INST: + SMMUL_INST: + SMUAD_INST: + SMUL_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + smul_inst *inst_cream = (smul_inst *)inst_base->component; + uint32_t operand1, operand2; + if (inst_cream->x == 0) + operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); + else + operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); + + if (inst_cream->y == 0) + operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); + else + operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); + RD = operand1 * operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smul_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SMULL_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + umull_inst *inst_cream = (umull_inst *)inst_base->component; + int64_t rm = RM; + int64_t rs = RS; + if (BIT(rm, 31)) { + rm |= 0xffffffff00000000LL; + } + if (BIT(rs, 31)) { + rs |= 0xffffffff00000000LL; + } + int64_t rst = rm * rs; + RDHI = BITS(rst, 32, 63); + RDLO = BITS(rst, 0, 31); + + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(umull_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SMULW_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + smlad_inst *inst_cream = (smlad_inst *)inst_base->component; + int64_t rm = RM; + int64_t rn = RN; + if (inst_cream->m) + rm = BITS(rm, 16, 31); + else + rm = BITS(rm, 0, 15); + int64_t rst = rm * rn; + RD = BITS(rst, 16, 47); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SMUSD_INST: + SRS_INST: + SSAT_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; + + u8 shift_type = inst_cream->shift_type; + u8 shift_amount = inst_cream->imm5; + u32 rn_val = RN; + + // 32-bit ASR is encoded as an amount of 0. + if (shift_type == 1 && shift_amount == 0) + shift_amount = 31; + + if (shift_type == 0) + rn_val <<= shift_amount; + else if (shift_type == 1) + rn_val = ((s32)rn_val >> shift_amount); + + bool saturated = false; + rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated); + + if (saturated) + cpu->Cpsr |= (1 << 27); + + RD = rn_val; + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ssat_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + SSAT16_INST: + SSUB8_INST: + STC_INST: + { + // Instruction not implemented + //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(stc_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STM_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + unsigned int inst = inst_cream->inst; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + int i; + unsigned int Rn = BITS(inst, 16, 19); + unsigned int old_RN = cpu->Reg[Rn]; + + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + if (BIT(inst_cream->inst, 22) == 1) { + for (i = 0; i < 13; i++) { + if(BIT(inst_cream->inst, i)){ + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); + if (fault) goto MMU_EXCEPTION; + addr += 4; + phys_addr += 4; + } + } + if (BIT(inst_cream->inst, 13)) { + if (cpu->Mode == USER32MODE) { + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); + if (fault) goto MMU_EXCEPTION; + addr += 4; + phys_addr += 4; + } else { + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); + if (fault) goto MMU_EXCEPTION; + addr += 4; + phys_addr += 4; + } + } + if (BIT(inst_cream->inst, 14)) { + if (cpu->Mode == USER32MODE) { + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); + if (fault) goto MMU_EXCEPTION; + addr += 4; + phys_addr += 4; + } else { + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); + if (fault) goto MMU_EXCEPTION; + addr += 4; + phys_addr += 4; + } + } + if (BIT(inst_cream->inst, 15)) { + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); + if (fault) goto MMU_EXCEPTION; + } + } else { + for( i = 0; i < 15; i ++ ) { + if(BIT(inst_cream->inst, i)) { + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + if(i == Rn) + fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); + else + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); + if (fault) goto MMU_EXCEPTION; + addr += 4; + phys_addr += 4; + } + } + + // Check PC reg + if(BIT(inst_cream->inst, i)) { + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); + if (fault) goto MMU_EXCEPTION; + } + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SXTB_INST: + { + sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_cream->Rm == 15) { + LOG_ERROR(Core_ARM11, "invalid operand for SXTB"); + CITRA_IGNORE_EXIT(-1); + } + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); + if (BIT(operand2, 7)) { + operand2 |= 0xffffff00; + } else + operand2 &= 0xff; + RD = operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(sxtb_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STR_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; + fault = interpreter_write_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UXTB_INST: + { + uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) + & 0xff; + RD = operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(uxtb_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UXTAB_INST: + { + uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) + & 0xff; + RD = RN + operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(uxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STRB_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; + fault = interpreter_write_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STRBT_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; + fault = interpreter_write_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STRD_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + uint32_t rear_phys_addr; + fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); if (fault){ - ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n"); - CITRA_IGNORE_EXIT(-1); - goto MMU_EXCEPTION; - } - - //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0); - //if (fault) goto MMU_EXCEPTION; - - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; - //bus_write(32, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; - //bus_write(32, addr, value); - fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STREX_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_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)]; - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - - int dest_reg = BITS(inst_cream->inst, 12, 15); - if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ - remove_exclusive(cpu, phys_addr); - cpu->Reg[dest_reg] = 0; - cpu->exclusive_state = 0; - - // bus_write(32, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - } - else{ - /* Failed to write due to mutex access */ - cpu->Reg[dest_reg] = 1; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STREXB_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_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; - fault = check_address_validity(cpu, addr, &phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - //bus_write(8, addr, value); - int dest_reg = BITS(inst_cream->inst, 12, 15); - if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ - remove_exclusive(cpu, phys_addr); - cpu->Reg[dest_reg] = 0; - cpu->exclusive_state = 0; - fault = interpreter_write_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - - } - else{ - cpu->Reg[dest_reg] = 1; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRH_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; - //bus_write(16, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 16); - if (fault) goto MMU_EXCEPTION; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - //if (BITS(inst_cream->inst, 12, 15) == 15) - // goto DISPATCH; - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRT_INST: - { - INC_ICOUNTER; - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); - if (fault) goto MMU_EXCEPTION; - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; - //bus_write(16, addr, value); - fault = interpreter_write_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SUB_INST: - { - INC_ICOUNTER; - sub_inst *inst_cream = (sub_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - if (inst_cream->Rn == 15) { - lop += 8; - } - rop = SHIFTER_OPERAND; - RD = dst = lop - rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - /* cpsr = spsr */ - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - switch_mode(cpu, cpu->Spsr_copy & 0x1f); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); -// UPDATE_CFLAG(dst, lop, rop); - UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); - // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); - UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(sub_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(sub_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SWI_INST: - { - INC_ICOUNTER; - swi_inst *inst_cream = (swi_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode - //arm_dyncom_SWI(cpu, inst_cream->num); - HLE::CallSVC(Memory::Read32(cpu->Reg[15])); - } else { - cpu->syscallSig = 1; - goto END; - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(swi_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SWP_INST: - { - INC_ICOUNTER; - swp_inst *inst_cream = (swp_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = RN; - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 32); - if (fault) goto MMU_EXCEPTION; - fault = interpreter_write_memory(addr, phys_addr, RM, 32); - if (fault) goto MMU_EXCEPTION; - - /* ROR(data, 8*UInt(address<1:0>)); */ - assert((phys_addr & 0x3) == 0); - RD = value; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(swp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SWPB_INST: - { - INC_ICOUNTER; - swp_inst *inst_cream = (swp_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - addr = RN; - fault = check_address_validity(cpu, addr, &phys_addr, 1); - if (fault) goto MMU_EXCEPTION; - unsigned int value; - fault = interpreter_read_memory(addr, phys_addr, value, 8); - if (fault) goto MMU_EXCEPTION; - fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); - if (fault) goto MMU_EXCEPTION; - - /* FIXME */ - #if 0 - if Shared(address) then - /* ARMv6 */ - physical_address = TLB(address) - ClearExclusiveByAddress(physical_address,processor_id,1) - /* See Summary of operation on page A2-49 */ - #endif - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(swp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SXTAB_INST: - { - INC_ICOUNTER; - sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - /* R15 should be check */ - if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ - CITRA_IGNORE_EXIT(-1); - } - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xff; - /* sign extend for byte */ - operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; - RD = RN + operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(uxtab_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SXTAB16_INST: - SXTAH_INST: - { - INC_ICOUNTER; - sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - /* R15 should be check */ - if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ - CITRA_IGNORE_EXIT(-1); - } - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; - /* sign extend for half */ - operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2; - RD = RN + operand2; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(sxtah_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SXTB16_INST: - TEQ_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - teq_inst *inst_cream = (teq_inst *)inst_base->component; - lop = RN; - if (inst_cream->Rn == 15) - lop += GET_INST_SIZE(cpu) * 2; - - rop = SHIFTER_OPERAND; - dst = lop ^ rop; - - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(teq_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - TST_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - tst_inst *inst_cream = (tst_inst *)inst_base->component; - lop = RN; - if (inst_cream->Rn == 15) - lop += GET_INST_SIZE(cpu) * 2; - rop = SHIFTER_OPERAND; - dst = lop & rop; - - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_WITH_SC; - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(tst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UADD16_INST: - UADD8_INST: - UADDSUBX_INST: - UHADD16_INST: - UHADD8_INST: - UHADDSUBX_INST: - UHSUB16_INST: - UHSUB8_INST: - UHSUBADDX_INST: - UMAAL_INST: - UMLAL_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; - unsigned long long int rm = RM; - unsigned long long int rs = RS; - unsigned long long int rst = rm * rs; - unsigned long long int add = ((unsigned long long) RDHI)<<32; - add += RDLO; - //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add); - rst += add; - RDLO = BITS(rst, 0, 31); - RDHI = BITS(rst, 32, 63); - - if (inst_cream->S) - { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(umlal_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UMULL_INST: - { - INC_ICOUNTER; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umull_inst *inst_cream = (umull_inst *)inst_base->component; - unsigned long long int rm = RM; - unsigned long long int rs = RS; - unsigned long long int rst = rm * rs; -// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); - RDHI = BITS(rst, 32, 63); - RDLO = BITS(rst, 0, 31); - - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } - } - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(umull_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - B_2_THUMB: - { - INC_ICOUNTER; - b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; - cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; - //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); - INC_PC(sizeof(b_2_thumb)); - goto DISPATCH; - } - B_COND_THUMB: - { - INC_ICOUNTER; - b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; - if(CondPassed(cpu, inst_cream->cond)) - cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; - else - cpu->Reg[15] += 2; - //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]); - INC_PC(sizeof(b_cond_thumb)); - goto DISPATCH; - } - BL_1_THUMB: - { - INC_ICOUNTER; - bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; - cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; - //cpu->Reg[15] += 2; - //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); - - cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(bl_1_thumb)); - FETCH_INST; - GOTO_NEXT_INST; - - } - BL_2_THUMB: - { - INC_ICOUNTER; - bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; - int tmp = ((cpu->Reg[15] + 2) | 1); - cpu->Reg[15] = - (cpu->Reg[14] + inst_cream->imm); - cpu->Reg[14] = tmp; - //DEBUG_LOG(ARM11, " BL_2_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); - INC_PC(sizeof(bl_2_thumb)); - goto DISPATCH; - } - BLX_1_THUMB: - { - /* BLX 1 for armv5t and above */ - INC_ICOUNTER; - uint32 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; - //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, instr=0x%x\n", inst_cream->imm, cpu->Reg[14], inst_cream->instr); - cpu->Reg[14] = ((tmp + 2) | 1); - //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; - /* switch to arm state from thumb state */ - cpu->TFlag = 0; - //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, r15=0x%x, \n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]); - INC_PC(sizeof(blx_1_thumb)); - goto DISPATCH; - } - - UQADD16_INST: - UQADD8_INST: - UQADDSUBX_INST: - UQSUB16_INST: - UQSUB8_INST: - UQSUBADDX_INST: - USAD8_INST: - USADA8_INST: - USAT_INST: - USAT16_INST: - USUB16_INST: - USUB8_INST: - USUBADDX_INST: - UXTAB16_INST: - UXTB16_INST: - #define VFP_INTERPRETER_IMPL - #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" - #undef VFP_INTERPRETER_IMPL - MMU_EXCEPTION: - { - SAVE_NZCVT; - cpu->abortSig = true; - cpu->Aborted = ARMul_DataAbortV; - cpu->AbortAddr = addr; - cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; - cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; - cpu->NumInstrsToExecute = 0; - return num_instrs; - } - END: - { - SAVE_NZCVT; - cpu->NumInstrsToExecute = 0; - return num_instrs; - } - INIT_INST_LENGTH: - { -#if 0 - DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); - for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) - DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); - DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); -#endif + LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr"); + CITRA_IGNORE_EXIT(-1); + goto MMU_EXCEPTION; + } + + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; + fault = interpreter_write_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; + fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STREX_INST: + { + ldst_inst *inst_cream = (ldst_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)]; + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + + int dest_reg = BITS(inst_cream->inst, 12, 15); + if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ + remove_exclusive(cpu, phys_addr); + cpu->Reg[dest_reg] = 0; + cpu->exclusive_state = 0; + + fault = interpreter_write_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + } else { + // Failed to write due to mutex access + cpu->Reg[dest_reg] = 1; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STREXB_INST: + { + ldst_inst *inst_cream = (ldst_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; + fault = check_address_validity(cpu, addr, &phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + int dest_reg = BITS(inst_cream->inst, 12, 15); + if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ + remove_exclusive(cpu, phys_addr); + cpu->Reg[dest_reg] = 0; + cpu->exclusive_state = 0; + fault = interpreter_write_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + } else { + cpu->Reg[dest_reg] = 1; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STRH_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; + fault = interpreter_write_memory(addr, phys_addr, value, 16); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + STRT_INST: + { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); + if (fault) goto MMU_EXCEPTION; + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; + fault = interpreter_write_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SUB_INST: + { + sub_inst *inst_cream = (sub_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + lop = RN; + if (inst_cream->Rn == 15) { + lop += 8; + } + rop = SHIFTER_OPERAND; + RD = dst = lop - rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + switch_mode(cpu, cpu->Spsr_copy & 0x1f); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); + UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(sub_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(sub_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SWI_INST: + { + swi_inst *inst_cream = (swi_inst *)inst_base->component; + + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) + HLE::CallSVC(Memory::Read32(cpu->Reg[15])); + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(swi_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SWP_INST: + { + swp_inst *inst_cream = (swp_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + addr = RN; + fault = check_address_validity(cpu, addr, &phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 32); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, RM, 32); + if (fault) goto MMU_EXCEPTION; + + assert((phys_addr & 0x3) == 0); + RD = value; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(swp_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SWPB_INST: + { + swp_inst *inst_cream = (swp_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + addr = RN; + fault = check_address_validity(cpu, addr, &phys_addr, 1); + if (fault) goto MMU_EXCEPTION; + unsigned int value; + fault = interpreter_read_memory(addr, phys_addr, value, 8); + if (fault) goto MMU_EXCEPTION; + fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); + if (fault) goto MMU_EXCEPTION; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(swp_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SXTAB_INST: + { + sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + // R15 should be check + if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ + CITRA_IGNORE_EXIT(-1); + } + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; + + // Sign extend for byte + operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; + RD = RN + operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(uxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SXTAB16_INST: + SXTAH_INST: + { + sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + // R15 should be check + if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15) { + CITRA_IGNORE_EXIT(-1); + } + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; + // Sign extend for half + operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; + RD = RN + operand2; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(sxtah_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + SXTB16_INST: + TEQ_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + teq_inst *inst_cream = (teq_inst *)inst_base->component; + lop = RN; + + if (inst_cream->Rn == 15) + lop += GET_INST_SIZE(cpu) * 2; + + rop = SHIFTER_OPERAND; + dst = lop ^ rop; + + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(teq_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + TST_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + tst_inst *inst_cream = (tst_inst *)inst_base->component; + lop = RN; + + if (inst_cream->Rn == 15) + lop += GET_INST_SIZE(cpu) * 2; + + rop = SHIFTER_OPERAND; + dst = lop & rop; + + UPDATE_NFLAG(dst); + UPDATE_ZFLAG(dst); + UPDATE_CFLAG_WITH_SC; + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(tst_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UADD8_INST: + UADD16_INST: + UADDSUBX_INST: + + UHADD8_INST: + UHADD16_INST: + UHADDSUBX_INST: + UHSUBADDX_INST: + UHSUB8_INST: + UHSUB16_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + const u32 rm_val = RM; + const u32 rn_val = RN; + const u8 op2 = inst_cream->op2; + + if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) + { + u32 lo_val = 0; + u32 hi_val = 0; + + // UHADD16 + if (op2 == 0x00) { + lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + } + // UHASX + else if (op2 == 0x01) { + lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); + } + // UHSAX + else if (op2 == 0x02) { + lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); + } + // UHSUB16 + else if (op2 == 0x03) { + lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + } + + lo_val >>= 1; + hi_val >>= 1; + + RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); + } + else if (op2 == 0x04 || op2 == 0x07) { + u32 sum1; + u32 sum2; + u32 sum3; + u32 sum4; + + // UHADD8 + if (op2 == 0x04) { + sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); + sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); + sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); + sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); + } + // UHSUB8 + else { + sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); + sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); + sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); + sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); + } + + sum1 >>= 1; + sum2 >>= 1; + sum3 >>= 1; + sum4 >>= 1; + + RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); + } + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + UMAAL_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; + const u32 rm = RM; + const u32 rn = RN; + const u32 rd_lo = RDLO; + const u32 rd_hi = RDHI; + const u64 result = (rm * rn) + rd_lo + rd_hi; + + RDLO = (result & 0xFFFFFFFF); + RDHI = ((result >> 32) & 0xFFFFFFFF); + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(umaal_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UMLAL_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + umlal_inst *inst_cream = (umlal_inst *)inst_base->component; + unsigned long long int rm = RM; + unsigned long long int rs = RS; + unsigned long long int rst = rm * rs; + unsigned long long int add = ((unsigned long long) RDHI)<<32; + add += RDLO; + rst += add; + RDLO = BITS(rst, 0, 31); + RDHI = BITS(rst, 32, 63); + + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(umlal_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + UMULL_INST: + { + if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + umull_inst *inst_cream = (umull_inst *)inst_base->component; + unsigned long long int rm = RM; + unsigned long long int rs = RS; + unsigned long long int rst = rm * rs; + RDHI = BITS(rst, 32, 63); + RDLO = BITS(rst, 0, 31); + + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); + } + } + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(umull_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + B_2_THUMB: + { + b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; + cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; + INC_PC(sizeof(b_2_thumb)); + goto DISPATCH; + } + B_COND_THUMB: + { + b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; + + if(CondPassed(cpu, inst_cream->cond)) + cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; + else + cpu->Reg[15] += 2; + + INC_PC(sizeof(b_cond_thumb)); + goto DISPATCH; + } + BL_1_THUMB: + { + bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; + cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(bl_1_thumb)); + FETCH_INST; + GOTO_NEXT_INST; + } + BL_2_THUMB: + { + bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; + int tmp = ((cpu->Reg[15] + 2) | 1); + cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm); + cpu->Reg[14] = tmp; + INC_PC(sizeof(bl_2_thumb)); + goto DISPATCH; + } + BLX_1_THUMB: + { + // BLX 1 for armv5t and above + uint32 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); + cpu->TFlag = 0; + INC_PC(sizeof(blx_1_thumb)); + goto DISPATCH; + } + + UQADD8_INST: + UQADD16_INST: + UQADDSUBX_INST: + UQSUB8_INST: + UQSUB16_INST: + UQSUBADDX_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + + const u8 op2 = inst_cream->op2; + const u32 rm_val = RM; + const u32 rn_val = RN; + + u16 lo_val = 0; + u16 hi_val = 0; + + // UQADD16 + if (op2 == 0x00) { + lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + } + // UQASX + else if (op2 == 0x01) { + lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + } + // UQSAX + else if (op2 == 0x02) { + lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + } + // UQSUB16 + else if (op2 == 0x03) { + lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + } + // UQADD8 + else if (op2 == 0x04) { + lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | + ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; + hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | + ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; + } + // UQSUB8 + else { + lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | + ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; + hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | + ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; + } + + RD = ((lo_val & 0xFFFF) | hi_val << 16); + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + USAD8_INST: + USADA8_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + + const u8 ra_idx = inst_cream->Ra; + const u32 rm_val = RM; + const u32 rn_val = RN; + + const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); + const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); + const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); + const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); + + u32 finalDif = (diff1 + diff2 + diff3 + diff4); + + // Op is USADA8 if true. + if (ra_idx != 15) + finalDif += cpu->Reg[ra_idx]; + + RD = finalDif; + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + USAT_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; + + u8 shift_type = inst_cream->shift_type; + u8 shift_amount = inst_cream->imm5; + u32 rn_val = RN; + + // 32-bit ASR is encoded as an amount of 0. + if (shift_type == 1 && shift_amount == 0) + shift_amount = 31; + + if (shift_type == 0) + rn_val <<= shift_amount; + else if (shift_type == 1) + rn_val = ((s32)rn_val >> shift_amount); + + bool saturated = false; + rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated); + + if (saturated) + cpu->Cpsr |= (1 << 27); + + RD = rn_val; + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(ssat_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + USAT16_INST: + USUB16_INST: + USUB8_INST: + USUBADDX_INST: + UXTAB16_INST: + UXTB16_INST: + { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; + + const u8 rn_idx = inst_cream->Rn; + const u32 rm_val = RM; + const u32 rotation = inst_cream->rotate * 8; + const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); + + // UXTB16, otherwise UXTAB16 + if (rn_idx == 15) { + RD = rotated_rm & 0x00FF00FF; + } else { + const u32 rn_val = RN; + const u8 lo_rotated = (rotated_rm & 0xFF); + const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; + const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; + const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; + + RD = ((hi_result << 16) | (lo_result & 0xFFFF)); + } + } + + cpu->Reg[15] += GET_INST_SIZE(cpu); + INC_PC(sizeof(uxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; + } + + #define VFP_INTERPRETER_IMPL + #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" + #undef VFP_INTERPRETER_IMPL + MMU_EXCEPTION: + { + SAVE_NZCVT; + cpu->abortSig = true; + cpu->Aborted = ARMul_DataAbortV; + cpu->AbortAddr = addr; + cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; + cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; + cpu->NumInstrsToExecute = 0; + return num_instrs; + } + END: + { + SAVE_NZCVT; + cpu->NumInstrsToExecute = 0; + return num_instrs; + } + INIT_INST_LENGTH: + { #if defined __GNUC__ || defined __clang__ - InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); + InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); #endif -#if 0 - for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) - DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); - DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]); - DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]); - DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]); -#endif - cpu->NumInstrsToExecute = 0; - return num_instrs; - } + cpu->NumInstrsToExecute = 0; + return num_instrs; + } } - diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h index 3a2462f55..4791ea25f 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.h +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp index a2026cbf3..d457d0ac5 100644 --- a/src/core/arm/dyncom/arm_dyncom_run.cpp +++ b/src/core/arm/dyncom/arm_dyncom_run.cpp @@ -1,42 +1,15 @@ -/* Copyright (C) -* 2011 - 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_run.cpp -* @brief The dyncom run implementation for arm -* @author Michael.Kang blackfin.kang@gmail.com -* @version 78.77 -* @date 2011-11-20 -*/ +// Copyright 2012 Michael Kang, 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. #include <assert.h> #include "core/arm/skyeye_common/armdefs.h" -void switch_mode(arm_core_t *core, uint32_t mode) -{ - uint32_t tmp1, tmp2; - if (core->Mode == mode) { - //Mode not changed. - //printf("mode not changed\n"); +void switch_mode(arm_core_t *core, uint32_t mode) { + if (core->Mode == mode) return; - } - //printf("%d --->>> %d\n", core->Mode, mode); - //printf("In %s, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter); + if (mode != USERBANK) { switch (core->Mode) { case USER32MODE: @@ -110,11 +83,8 @@ void switch_mode(arm_core_t *core, uint32_t mode) } core->Mode = mode; - //printf("In %si end, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter); - //printf("\n--------------------------------------\n"); - } - else { - printf("user mode\n"); + } else { + LOG_CRITICAL(Core_ARM11, "user mode"); exit(-2); } } diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index e10f2f9ee..de70ca8ae 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp @@ -1,35 +1,13 @@ -/* Copyright (C) -* 2011 - 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_thumb.c -* @brief The thumb dynamic interpreter -* @author Michael.Kang blackfin.kang@gmail.com -* @version 78.77 -* @date 2011-11-07 -*/ - -/* We can provide simple Thumb simulation by decoding the Thumb -instruction into its corresponding ARM instruction, and using the -existing ARM simulator. */ +// Copyright 2012 Michael Kang, 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// We can provide simple Thumb simulation by decoding the Thumb instruction into its corresponding +// ARM instruction, and using the existing ARM simulator. #include "core/arm/skyeye_common/skyeye_defs.h" -#ifndef MODET /* required for the Thumb instruction support */ +#ifndef MODET // Required for the Thumb instruction support #if 1 #error "MODET needs to be defined for the Thumb world to work" #else @@ -40,482 +18,359 @@ existing ARM simulator. */ #include "core/arm/skyeye_common/armos.h" #include "core/arm/dyncom/arm_dyncom_thumb.h" -/* Decode a 16bit Thumb instruction. The instruction is in the low - 16-bits of the tinstr field, with the following Thumb instruction - held in the high 16-bits. Passing in two Thumb instructions allows - easier simulation of the special dual BL instruction. */ +// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, +// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions +// allows easier simulation of the special dual BL instruction. -tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) -{ +tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) { tdstate valid = t_uninitialized; - ARMword next_instr; - ARMword tinstr; - tinstr = instr; - /* The endian should be judge here */ - #if 0 - if (state->bigendSig) { - next_instr = tinstr & 0xFFFF; - tinstr >>= 16; - } - else { - next_instr = tinstr >> 16; - tinstr &= 0xFFFF; - } - #endif - if((addr & 0x3) != 0) - tinstr = instr >> 16; - else - tinstr &= 0xFFFF; - - //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc); -#if 1 /* debugging to catch non updates */ - *ainstr = 0xDEADC0DE; -#endif + ARMword tinstr; + tinstr = instr; + + // The endian should be judge here + if((addr & 0x3) != 0) + tinstr = instr >> 16; + else + tinstr &= 0xFFFF; + + *ainstr = 0xDEADC0DE; // Debugging to catch non updates + + switch ((tinstr & 0xF800) >> 11) { + case 0: // LSL + case 1: // LSR + case 2: // ASR + *ainstr = 0xE1B00000 // base opcode + | ((tinstr & 0x1800) >> (11 - 5)) // shift type + |((tinstr & 0x07C0) << (7 - 6)) // imm5 + |((tinstr & 0x0038) >> 3) // Rs + |((tinstr & 0x0007) << 12); // Rd + break; + + case 3: // ADD/SUB + { + ARMword subset[4] = { + 0xE0900000, // ADDS Rd,Rs,Rn + 0xE0500000, // SUBS Rd,Rs,Rn + 0xE2900000, // ADDS Rd,Rs,#imm3 + 0xE2500000 // SUBS Rd,Rs,#imm3 + }; + // It is quicker indexing into a table, than performing switch or conditionals: + *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode + |((tinstr & 0x01C0) >> 6) // Rn or imm3 + |((tinstr & 0x0038) << (16 - 3)) // Rs + |((tinstr & 0x0007) << (12 - 0)); // Rd + } + break; + + case 4: // MOV + case 5: // CMP + case 6: // ADD + case 7: // SUB + { + ARMword subset[4] = { + 0xE3B00000, // MOVS Rd,#imm8 + 0xE3500000, // CMP Rd,#imm8 + 0xE2900000, // ADDS Rd,Rd,#imm8 + 0xE2500000, // SUBS Rd,Rd,#imm8 + }; + + *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode + |((tinstr & 0x00FF) >> 0) // imm8 + |((tinstr & 0x0700) << (16 - 8)) // Rn + |((tinstr & 0x0700) << (12 - 8)); // Rd + } + break; + + case 8: // Arithmetic and high register transfers + + // TODO: Since the subsets for both Format 4 and Format 5 instructions are made up of + // different ARM encodings, we could save the following conditional, and just have one + // large subset + + if ((tinstr & (1 << 10)) == 0) { + enum otype { + t_norm, + t_shift, + t_neg, + t_mul + }; + + struct { + ARMword opcode; + otype type; + } subset[16] = { + { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs + { 0xE0300000, t_norm }, // EORS Rd,Rd,Rs + { 0xE1B00010, t_shift }, // MOVS Rd,Rd,LSL Rs + { 0xE1B00030, t_shift }, // MOVS Rd,Rd,LSR Rs + { 0xE1B00050, t_shift }, // MOVS Rd,Rd,ASR Rs + { 0xE0B00000, t_norm }, // ADCS Rd,Rd,Rs + { 0xE0D00000, t_norm }, // SBCS Rd,Rd,Rs + { 0xE1B00070, t_shift }, // MOVS Rd,Rd,ROR Rs + { 0xE1100000, t_norm }, // TST Rd,Rs + { 0xE2700000, t_neg }, // RSBS Rd,Rs,#0 + { 0xE1500000, t_norm }, // CMP Rd,Rs + { 0xE1700000, t_norm }, // CMN Rd,Rs + { 0xE1900000, t_norm }, // ORRS Rd,Rd,Rs + { 0xE0100090, t_mul }, // MULS Rd,Rd,Rs + { 0xE1D00000, t_norm }, // BICS Rd,Rd,Rs + { 0xE1F00000, t_norm } // MVNS Rd,Rs + }; + + *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base + + switch (subset[(tinstr & 0x03C0) >> 6].type) { + case t_norm: + *ainstr |= ((tinstr & 0x0007) << 16) // Rn + |((tinstr & 0x0007) << 12) // Rd + |((tinstr & 0x0038) >> 3); // Rs + break; + case t_shift: + *ainstr |= ((tinstr & 0x0007) << 12) // Rd + |((tinstr & 0x0007) >> 0) // Rm + |((tinstr & 0x0038) << (8 - 3)); // Rs + break; + case t_neg: + *ainstr |= ((tinstr & 0x0007) << 12) // Rd + |((tinstr & 0x0038) << (16 - 3)); // Rn + break; + case t_mul: + *ainstr |= ((tinstr & 0x0007) << 16) // Rd + |((tinstr & 0x0007) << 8) // Rs + |((tinstr & 0x0038) >> 3); // Rm + break; + } + } else { + ARMword Rd = ((tinstr & 0x0007) >> 0); + ARMword Rs = ((tinstr & 0x0038) >> 3); + + if (tinstr & (1 << 7)) + Rd += 8; + if (tinstr & (1 << 6)) + Rs += 8; + + switch ((tinstr & 0x03C0) >> 6) { + case 0x1: // ADD Rd,Rd,Hs + case 0x2: // ADD Hd,Hd,Rs + case 0x3: // ADD Hd,Hd,Hs + *ainstr = 0xE0800000 // base + | (Rd << 16) // Rn + |(Rd << 12) // Rd + |(Rs << 0); // Rm + break; + case 0x5: // CMP Rd,Hs + case 0x6: // CMP Hd,Rs + case 0x7: // CMP Hd,Hs + *ainstr = 0xE1500000 // base + | (Rd << 16) // Rn + |(Rd << 12) // Rd + |(Rs << 0); // Rm + break; + case 0x9: // MOV Rd,Hs + case 0xA: // MOV Hd,Rs + case 0xB: // MOV Hd,Hs + *ainstr = 0xE1A00000 // base + | (Rd << 16) // Rn + |(Rd << 12) // Rd + |(Rs << 0); // Rm + break; + case 0xC: // BX Rs + case 0xD: // BX Hs + *ainstr = 0xE12FFF10 // base + | ((tinstr & 0x0078) >> 3); // Rd + break; + case 0x0: // UNDEFINED + case 0x4: // UNDEFINED + case 0x8: // UNDEFINED + valid = t_undefined; + break; + case 0xE: // BLX + case 0xF: // BLX + *ainstr = 0xE1200030 // base + | (Rs << 0); // Rm + break; + } + } + break; + + case 9: // LDR Rd,[PC,#imm8] + *ainstr = 0xE59F0000 // base + | ((tinstr & 0x0700) << (12 - 8)) // Rd + |((tinstr & 0x00FF) << (2 - 0)); // off8 + break; + + case 10: + case 11: + // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be + // merged into a single subset, saving on the following boolean: + + if ((tinstr & (1 << 9)) == 0) { + ARMword subset[4] = { + 0xE7800000, // STR Rd,[Rb,Ro] + 0xE7C00000, // STRB Rd,[Rb,Ro] + 0xE7900000, // LDR Rd,[Rb,Ro] + 0xE7D00000 // LDRB Rd,[Rb,Ro] + }; + + *ainstr = subset[(tinstr & 0x0C00) >> 10] // base + |((tinstr & 0x0007) << (12 - 0)) // Rd + |((tinstr & 0x0038) << (16 - 3)) // Rb + |((tinstr & 0x01C0) >> 6); // Ro + + } else { + ARMword subset[4] = { + 0xE18000B0, // STRH Rd,[Rb,Ro] + 0xE19000D0, // LDRSB Rd,[Rb,Ro] + 0xE19000B0, // LDRH Rd,[Rb,Ro] + 0xE19000F0 // LDRSH Rd,[Rb,Ro] + }; + *ainstr = subset[(tinstr & 0x0C00) >> 10] // base + |((tinstr & 0x0007) << (12 - 0)) // Rd + |((tinstr & 0x0038) << (16 - 3)) // Rb + |((tinstr & 0x01C0) >> 6); // Ro + } + break; + + case 12: // STR Rd,[Rb,#imm5] + case 13: // LDR Rd,[Rb,#imm5] + case 14: // STRB Rd,[Rb,#imm5] + case 15: // LDRB Rd,[Rb,#imm5] + { + ARMword subset[4] = { + 0xE5800000, // STR Rd,[Rb,#imm5] + 0xE5900000, // LDR Rd,[Rb,#imm5] + 0xE5C00000, // STRB Rd,[Rb,#imm5] + 0xE5D00000 // LDRB Rd,[Rb,#imm5] + }; + // The offset range defends on whether we are transferring a byte or word value: + *ainstr = subset[(tinstr & 0x1800) >> 11] // base + |((tinstr & 0x0007) << (12 - 0)) // Rd + |((tinstr & 0x0038) << (16 - 3)) // Rb + |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5 + } + break; + + case 16: // STRH Rd,[Rb,#imm5] + case 17: // LDRH Rd,[Rb,#imm5] + *ainstr = ((tinstr & (1 << 11)) // base + ? 0xE1D000B0 // LDRH + : 0xE1C000B0) // STRH + |((tinstr & 0x0007) << (12 - 0)) // Rd + |((tinstr & 0x0038) << (16 - 3)) // Rb + |((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble + |((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble + break; + + case 18: // STR Rd,[SP,#imm8] + case 19: // LDR Rd,[SP,#imm8] + *ainstr = ((tinstr & (1 << 11)) // base + ? 0xE59D0000 // LDR + : 0xE58D0000) // STR + |((tinstr & 0x0700) << (12 - 8)) // Rd + |((tinstr & 0x00FF) << 2); // off8 + break; + + case 20: // ADD Rd,PC,#imm8 + case 21: // ADD Rd,SP,#imm8 + + if ((tinstr & (1 << 11)) == 0) { + + // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the + // rotate immediate field, so no shift of off8 is needed. + + *ainstr = 0xE28F0F00 // base + | ((tinstr & 0x0700) << (12 - 8)) // Rd + |(tinstr & 0x00FF); // off8 + } else { + // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is needed. + *ainstr = 0xE28D0F00 // base + | ((tinstr & 0x0700) << (12 - 8)) // Rd + |(tinstr & 0x00FF); // off8 + } + break; + + case 22: + case 23: + if ((tinstr & 0x0F00) == 0x0000) { + // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30): + *ainstr = ((tinstr & (1 << 7)) // base + ? 0xE24DDF00 // SUB + : 0xE28DDF00) // ADD + |(tinstr & 0x007F); // off7 + } else if ((tinstr & 0x0F00) == 0x0e00) + *ainstr = 0xEF000000 | SWI_Breakpoint; + else { + ARMword subset[4] = { + 0xE92D0000, // STMDB sp!,{rlist} + 0xE92D4000, // STMDB sp!,{rlist,lr} + 0xE8BD0000, // LDMIA sp!,{rlist} + 0xE8BD8000 // LDMIA sp!,{rlist,pc} + }; + *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base + |(tinstr & 0x00FF); // mask8 + } + break; + + case 24: // STMIA + case 25: // LDMIA + *ainstr = ((tinstr & (1 << 11)) // base + ? 0xE8B00000 // LDMIA + : 0xE8A00000) // STMIA + |((tinstr & 0x0700) << (16 - 8)) // Rb + |(tinstr & 0x00FF); // mask8 + break; + + case 26: // Bcc + case 27: // Bcc/SWI + if ((tinstr & 0x0F00) == 0x0F00) { + // Format 17 : SWI + *ainstr = 0xEF000000; + // Breakpoint must be handled specially. + if ((tinstr & 0x00FF) == 0x18) + *ainstr |= ((tinstr & 0x00FF) << 16); + // New breakpoint value. See gdb/arm-tdep.c + else if ((tinstr & 0x00FF) == 0xFE) + *ainstr |= SWI_Breakpoint; + else + *ainstr |= (tinstr & 0x00FF); + } else if ((tinstr & 0x0F00) != 0x0E00) + valid = t_branch; + else // UNDEFINED : cc=1110(AL) uses different format + valid = t_undefined; + + break; + + case 28: // B + valid = t_branch; + break; + + case 29: + if(tinstr & 0x1) + valid = t_undefined; + else + valid = t_branch; + break; + + case 30: // BL instruction 1 + + // There is no single ARM instruction equivalent for this Thumb instruction. To keep the + // simulation simple (from the user perspective) we check if the following instruction is + // the second half of this BL, and if it is we simulate it immediately + + valid = t_branch; + break; + + case 31: // BL instruction 2 + + // There is no single ARM instruction equivalent for this instruction. Also, it should only + // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the + // simulation of it on its own, with undefined results if r14 is not suitably initialised. + + valid = t_branch; + break; + } + + *inst_size = 2; - switch ((tinstr & 0xF800) >> 11) { - case 0: /* LSL */ - case 1: /* LSR */ - case 2: /* ASR */ - /* Format 1 */ - *ainstr = 0xE1B00000 /* base opcode */ - | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */ - |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */ - |((tinstr & 0x0038) >> 3) /* Rs */ - |((tinstr & 0x0007) << 12); /* Rd */ - break; - case 3: /* ADD/SUB */ - /* Format 2 */ - { - ARMword subset[4] = { - 0xE0900000, /* ADDS Rd,Rs,Rn */ - 0xE0500000, /* SUBS Rd,Rs,Rn */ - 0xE2900000, /* ADDS Rd,Rs,#imm3 */ - 0xE2500000 /* SUBS Rd,Rs,#imm3 */ - }; - /* It is quicker indexing into a table, than performing switch - or conditionals: */ - *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */ - |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */ - |((tinstr & 0x0038) << (16 - 3)) /* Rs */ - |((tinstr & 0x0007) << (12 - 0)); /* Rd */ - } - break; - case 4: /* MOV */ - case 5: /* CMP */ - case 6: /* ADD */ - case 7: /* SUB */ - /* Format 3 */ - { - ARMword subset[4] = { - 0xE3B00000, /* MOVS Rd,#imm8 */ - 0xE3500000, /* CMP Rd,#imm8 */ - 0xE2900000, /* ADDS Rd,Rd,#imm8 */ - 0xE2500000, /* SUBS Rd,Rd,#imm8 */ - }; - *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */ - |((tinstr & 0x00FF) >> 0) /* imm8 */ - |((tinstr & 0x0700) << (16 - 8)) /* Rn */ - |((tinstr & 0x0700) << (12 - 8)); /* Rd */ - } - break; - case 8: /* Arithmetic and high register transfers */ - /* TODO: Since the subsets for both Format 4 and Format 5 - instructions are made up of different ARM encodings, we could - save the following conditional, and just have one large - subset. */ - if ((tinstr & (1 << 10)) == 0) { - typedef enum - { t_norm, t_shift, t_neg, t_mul }otype_t; - - /* Format 4 */ - struct - { - ARMword opcode; - otype_t otype; - } - subset[16] = { - { - 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */ - { - 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */ - { - 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */ - { - 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */ - { - 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */ - { - 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */ - { - 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */ - { - 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */ - { - 0xE1100000, t_norm}, /* TST Rd,Rs */ - { - 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */ - { - 0xE1500000, t_norm}, /* CMP Rd,Rs */ - { - 0xE1700000, t_norm}, /* CMN Rd,Rs */ - { - 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */ - { - 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */ - { - 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */ - { - 0xE1F00000, t_norm} /* MVNS Rd,Rs */ - }; - *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */ - switch (subset[(tinstr & 0x03C0) >> 6].otype) { - case t_norm: - *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */ - |((tinstr & 0x0007) << 12) /* Rd */ - |((tinstr & 0x0038) >> 3); /* Rs */ - break; - case t_shift: - *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ - |((tinstr & 0x0007) >> 0) /* Rm */ - |((tinstr & 0x0038) << (8 - 3)); /* Rs */ - break; - case t_neg: - *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)); /* Rn */ - break; - case t_mul: - *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */ - |((tinstr & 0x0007) << 8) /* Rs */ - |((tinstr & 0x0038) >> 3); /* Rm */ - break; - } - } - else { - /* Format 5 */ - ARMword Rd = ((tinstr & 0x0007) >> 0); - ARMword Rs = ((tinstr & 0x0038) >> 3); - if (tinstr & (1 << 7)) - Rd += 8; - if (tinstr & (1 << 6)) - Rs += 8; - switch ((tinstr & 0x03C0) >> 6) { - case 0x1: /* ADD Rd,Rd,Hs */ - case 0x2: /* ADD Hd,Hd,Rs */ - case 0x3: /* ADD Hd,Hd,Hs */ - *ainstr = 0xE0800000 /* base */ - | (Rd << 16) /* Rn */ - |(Rd << 12) /* Rd */ - |(Rs << 0); /* Rm */ - break; - case 0x5: /* CMP Rd,Hs */ - case 0x6: /* CMP Hd,Rs */ - case 0x7: /* CMP Hd,Hs */ - *ainstr = 0xE1500000 /* base */ - | (Rd << 16) /* Rn */ - |(Rd << 12) /* Rd */ - |(Rs << 0); /* Rm */ - break; - case 0x9: /* MOV Rd,Hs */ - case 0xA: /* MOV Hd,Rs */ - case 0xB: /* MOV Hd,Hs */ - *ainstr = 0xE1A00000 /* base */ - | (Rd << 16) /* Rn */ - |(Rd << 12) /* Rd */ - |(Rs << 0); /* Rm */ - break; - case 0xC: /* BX Rs */ - case 0xD: /* BX Hs */ - *ainstr = 0xE12FFF10 /* base */ - | ((tinstr & 0x0078) >> 3); /* Rd */ - break; - case 0x0: /* UNDEFINED */ - case 0x4: /* UNDEFINED */ - case 0x8: /* UNDEFINED */ - valid = t_undefined; - break; - case 0xE: /* BLX */ - case 0xF: /* BLX */ - - //if (state->is_v5) { - if(1){ - //valid = t_branch; - #if 1 - *ainstr = 0xE1200030 /* base */ - |(Rs << 0); /* Rm */ - #endif - } else { - valid = t_undefined; - } - break; - } - } - break; - case 9: /* LDR Rd,[PC,#imm8] */ - /* Format 6 */ - *ainstr = 0xE59F0000 /* base */ - | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |((tinstr & 0x00FF) << (2 - 0)); /* off8 */ - break; - case 10: - case 11: - /* TODO: Format 7 and Format 8 perform the same ARM encoding, so - the following could be merged into a single subset, saving on - the following boolean: */ - if ((tinstr & (1 << 9)) == 0) { - /* Format 7 */ - ARMword subset[4] = { - 0xE7800000, /* STR Rd,[Rb,Ro] */ - 0xE7C00000, /* STRB Rd,[Rb,Ro] */ - 0xE7900000, /* LDR Rd,[Rb,Ro] */ - 0xE7D00000 /* LDRB Rd,[Rb,Ro] */ - }; - *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x01C0) >> 6); /* Ro */ - } - else { - /* Format 8 */ - ARMword subset[4] = { - 0xE18000B0, /* STRH Rd,[Rb,Ro] */ - 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */ - 0xE19000B0, /* LDRH Rd,[Rb,Ro] */ - 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */ - }; - *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x01C0) >> 6); /* Ro */ - } - break; - case 12: /* STR Rd,[Rb,#imm5] */ - case 13: /* LDR Rd,[Rb,#imm5] */ - case 14: /* STRB Rd,[Rb,#imm5] */ - case 15: /* LDRB Rd,[Rb,#imm5] */ - /* Format 9 */ - { - ARMword subset[4] = { - 0xE5800000, /* STR Rd,[Rb,#imm5] */ - 0xE5900000, /* LDR Rd,[Rb,#imm5] */ - 0xE5C00000, /* STRB Rd,[Rb,#imm5] */ - 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */ - }; - /* The offset range defends on whether we are transferring a - byte or word value: */ - *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */ - } - break; - case 16: /* STRH Rd,[Rb,#imm5] */ - case 17: /* LDRH Rd,[Rb,#imm5] */ - /* Format 10 */ - *ainstr = ((tinstr & (1 << 11)) /* base */ - ? 0xE1D000B0 /* LDRH */ - : 0xE1C000B0) /* STRH */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */ - |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */ - break; - case 18: /* STR Rd,[SP,#imm8] */ - case 19: /* LDR Rd,[SP,#imm8] */ - /* Format 11 */ - *ainstr = ((tinstr & (1 << 11)) /* base */ - ? 0xE59D0000 /* LDR */ - : 0xE58D0000) /* STR */ - |((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |((tinstr & 0x00FF) << 2); /* off8 */ - break; - case 20: /* ADD Rd,PC,#imm8 */ - case 21: /* ADD Rd,SP,#imm8 */ - /* Format 12 */ - if ((tinstr & (1 << 11)) == 0) { - /* NOTE: The PC value used here should by word aligned */ - /* We encode shift-left-by-2 in the rotate immediate field, - so no shift of off8 is needed. */ - *ainstr = 0xE28F0F00 /* base */ - | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |(tinstr & 0x00FF); /* off8 */ - } - else { - /* We encode shift-left-by-2 in the rotate immediate field, - so no shift of off8 is needed. */ - *ainstr = 0xE28D0F00 /* base */ - | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |(tinstr & 0x00FF); /* off8 */ - } - break; - case 22: - case 23: - if ((tinstr & 0x0F00) == 0x0000) { - /* Format 13 */ - /* NOTE: The instruction contains a shift left of 2 - equivalent (implemented as ROR #30): */ - *ainstr = ((tinstr & (1 << 7)) /* base */ - ? 0xE24DDF00 /* SUB */ - : 0xE28DDF00) /* ADD */ - |(tinstr & 0x007F); /* off7 */ - } - else if ((tinstr & 0x0F00) == 0x0e00) - *ainstr = 0xEF000000 | SWI_Breakpoint; - else { - /* Format 14 */ - ARMword subset[4] = { - 0xE92D0000, /* STMDB sp!,{rlist} */ - 0xE92D4000, /* STMDB sp!,{rlist,lr} */ - 0xE8BD0000, /* LDMIA sp!,{rlist} */ - 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */ - }; - *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */ - |(tinstr & 0x00FF); /* mask8 */ - } - break; - case 24: /* STMIA */ - case 25: /* LDMIA */ - /* Format 15 */ - *ainstr = ((tinstr & (1 << 11)) /* base */ - ? 0xE8B00000 /* LDMIA */ - : 0xE8A00000) /* STMIA */ - |((tinstr & 0x0700) << (16 - 8)) /* Rb */ - |(tinstr & 0x00FF); /* mask8 */ - break; - case 26: /* Bcc */ - case 27: /* Bcc/SWI */ - if ((tinstr & 0x0F00) == 0x0F00) { - #if 0 - if (tinstr == (ARMul_ABORTWORD & 0xffff) && - state->AbortAddr == pc) { - *ainstr = ARMul_ABORTWORD; - break; - } - #endif - /* Format 17 : SWI */ - *ainstr = 0xEF000000; - /* Breakpoint must be handled specially. */ - if ((tinstr & 0x00FF) == 0x18) - *ainstr |= ((tinstr & 0x00FF) << 16); - /* New breakpoint value. See gdb/arm-tdep.c */ - else if ((tinstr & 0x00FF) == 0xFE) - *ainstr |= SWI_Breakpoint; - else - *ainstr |= (tinstr & 0x00FF); - } - else if ((tinstr & 0x0F00) != 0x0E00) { - /* Format 16 */ - #if 0 - int doit = FALSE; - /* TODO: Since we are doing a switch here, we could just add - the SWI and undefined instruction checks into this - switch to same on a couple of conditionals: */ - switch ((tinstr & 0x0F00) >> 8) { - case EQ: - doit = ZFLAG; - break; - case NE: - doit = !ZFLAG; - break; - case VS: - doit = VFLAG; - break; - case VC: - doit = !VFLAG; - break; - case MI: - doit = NFLAG; - break; - case PL: - doit = !NFLAG; - break; - case CS: - doit = CFLAG; - break; - case CC: - doit = !CFLAG; - break; - case HI: - doit = (CFLAG && !ZFLAG); - break; - case LS: - doit = (!CFLAG || ZFLAG); - break; - case GE: - doit = ((!NFLAG && !VFLAG) - || (NFLAG && VFLAG)); - break; - case LT: - doit = ((NFLAG && !VFLAG) - || (!NFLAG && VFLAG)); - break; - case GT: - doit = ((!NFLAG && !VFLAG && !ZFLAG) - || (NFLAG && VFLAG && !ZFLAG)); - break; - case LE: - doit = ((NFLAG && !VFLAG) - || (!NFLAG && VFLAG)) || ZFLAG; - break; - } - if (doit) { - state->Reg[15] = (pc + 4 - + (((tinstr & 0x7F) << 1) - | ((tinstr & (1 << 7)) ? - 0xFFFFFF00 : 0))); - FLUSHPIPE; - } - #endif - valid = t_branch; - } - else /* UNDEFINED : cc=1110(AL) uses different format */ - valid = t_undefined; - break; - case 28: /* B */ - /* Format 18 */ - #if 0 - state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1) - | ((tinstr & (1 << 10)) ? - 0xFFFFF800 : 0))); - #endif - //FLUSHPIPE; - valid = t_branch; - break; - case 29: - if(tinstr & 0x1) - valid = t_undefined; - else{ - /* BLX 1 for armv5t and above */ - //printf("In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1); - valid = t_branch; - } - break; - case 30: /* BL instruction 1 */ - /* Format 19 */ - /* There is no single ARM instruction equivalent for this Thumb - instruction. To keep the simulation simple (from the user - perspective) we check if the following instruction is the - second half of this BL, and if it is we simulate it - immediately. */ - valid = t_branch; - break; - case 31: /* BL instruction 2 */ - /* Format 19 */ - /* There is no single ARM instruction equivalent for this - instruction. Also, it should only ever be matched with the - fmt19 "BL instruction 1" instruction. However, we do allow - the simulation of it on its own, with undefined results if - r14 is not suitably initialised. */ - { - #if 0 - ARMword tmp = (pc + 2); - state->Reg[15] = - (state->Reg[14] + ((tinstr & 0x07FF) << 1)); - state->Reg[14] = (tmp | 1); - #endif - valid = t_branch; - } - break; - } - *inst_size = 2; - return valid; + return valid; } diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp index e2aa5ce92..80ebc359e 100644 --- a/src/core/arm/interpreter/arm_interpreter.cpp +++ b/src/core/arm/interpreter/arm_interpreter.cpp @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include "core/arm/interpreter/arm_interpreter.h" @@ -38,78 +38,43 @@ ARM_Interpreter::~ARM_Interpreter() { delete state; } -/** - * Set the Program Counter to an address - * @param addr Address to set PC to - */ void ARM_Interpreter::SetPC(u32 pc) { state->pc = state->Reg[15] = pc; } -/* - * Get the current Program Counter - * @return Returns current PC - */ u32 ARM_Interpreter::GetPC() const { return state->pc; } -/** - * Get an ARM register - * @param index Register index (0-15) - * @return Returns the value in the register - */ u32 ARM_Interpreter::GetReg(int index) const { return state->Reg[index]; } -/** - * Set an ARM register - * @param index Register index (0-15) - * @param value Value to set register to - */ void ARM_Interpreter::SetReg(int index, u32 value) { state->Reg[index] = value; } -/** - * Get the current CPSR register - * @return Returns the value of the CPSR register - */ u32 ARM_Interpreter::GetCPSR() const { return state->Cpsr; } -/** - * Set the current CPSR register - * @param cpsr Value to set CPSR to - */ void ARM_Interpreter::SetCPSR(u32 cpsr) { state->Cpsr = cpsr; } -/** - * Returns the number of clock ticks since the last reset - * @return Returns number of clock ticks - */ u64 ARM_Interpreter::GetTicks() const { - return ARMul_Time(state); + return state->NumInstrs; +} + +void ARM_Interpreter::AddTicks(u64 ticks) { + state->NumInstrs += ticks; } -/** - * Executes the given number of instructions - * @param num_instructions Number of instructions to executes - */ void ARM_Interpreter::ExecuteInstructions(int num_instructions) { state->NumInstrsToExecute = num_instructions - 1; ARMul_Emulate32(state); } -/** - * Saves the current CPU context - * @param ctx Thread context to save - * @todo Do we need to save Reg[15] and NextInstr? - */ void ARM_Interpreter::SaveContext(ThreadContext& ctx) { memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); @@ -126,11 +91,6 @@ void ARM_Interpreter::SaveContext(ThreadContext& ctx) { ctx.mode = state->NextInstr; } -/** - * Loads a CPU context - * @param ctx Thread context to load - * @param Do we need to load Reg[15] and NextInstr? - */ void ARM_Interpreter::LoadContext(const ThreadContext& ctx) { memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); @@ -147,7 +107,6 @@ void ARM_Interpreter::LoadContext(const ThreadContext& ctx) { state->NextInstr = ctx.mode; } -/// Prepare core for thread reschedule (if needed to correctly handle state) void ARM_Interpreter::PrepareReschedule() { state->NumInstrsToExecute = 0; } diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h index ed53d997c..019dad5df 100644 --- a/src/core/arm/interpreter/arm_interpreter.h +++ b/src/core/arm/interpreter/arm_interpreter.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once @@ -61,6 +61,12 @@ public: u64 GetTicks() const override; /** + * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) + * @param ticks Number of ticks to advance the CPU core + */ + void AddTicks(u64 ticks) override; + + /** * Saves the current CPU context * @param ctx Thread context to save */ diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 73223874e..b9c2aa6c2 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp @@ -949,7 +949,7 @@ ARMul_Emulate26 (ARMul_State * state) //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); if (armOp == 0xDEADC0DE) { - DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc); + LOG_ERROR(Core_ARM11, "Failed to decode thumb opcode %04X at %08X", instr, pc); } instr = armOp; @@ -1166,7 +1166,7 @@ mainswitch: else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) { //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) unsigned msb ,tmp_rn, tmp_rd, dst; - msb = tmp_rd = tmp_rn = dst = 0; + tmp_rd = tmp_rn = dst = 0; Rd = BITS(12, 15); Rn = BITS(0, 3); lsb = BITS(7, 11); @@ -1356,7 +1356,13 @@ mainswitch: } break; - case 0x04: /* SUB reg */ + case 0x04: /* SUB reg */ + // Signifies UMAAL + if (state->is_v6 && BITS(4, 7) == 0x09) { + if (handle_v6_insn(state, instr)) + break; + } + #ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, no write-back, down, post indexed. */ @@ -1664,7 +1670,7 @@ mainswitch: op1 *= op2; //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn); if (AddOverflow(op1, Rn, op1 + Rn)) - SETS; + SETQ; state->Reg[BITS (16, 19)] = op1 + Rn; break; } @@ -1676,7 +1682,7 @@ mainswitch: ARMword result = op1 + op2; if (AddOverflow(op1, op2, result)) { result = POS (result) ? 0x80000000 : 0x7fffffff; - SETS; + SETQ; } state->Reg[BITS (12, 15)] = result; break; @@ -1718,7 +1724,7 @@ mainswitch: TAKEABORT; } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */ UNDEF_MRSPC; - DEST = ECC | EINT | EMODE; + DEST = ARMul_GetCPSR(state); } else { UNDEF_Test; } @@ -1737,7 +1743,7 @@ mainswitch: //chy 2006-02-15 if in user mode, can not set cpsr 0:23 //from p165 of ARMARM book state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else rhs = DPRegRHS; temp = LHS & rhs; @@ -1789,7 +1795,7 @@ mainswitch: ARMword Rn = state->Reg[BITS(12, 15)]; if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn))) - SETS; + SETQ; result += Rn; } state->Reg[BITS (16, 19)] = (ARMword)result; @@ -1805,7 +1811,7 @@ mainswitch: if (SubOverflow (op1, op2, result)) { result = POS (result) ? 0x80000000 : 0x7fffffff; - SETS; + SETQ; } state->Reg[BITS (12, 15)] = result; @@ -1877,7 +1883,7 @@ mainswitch: /* TEQP reg */ #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else rhs = DPRegRHS; temp = LHS ^ rhs; @@ -1928,13 +1934,13 @@ mainswitch: if (AddOverflow (op2, op2, op2d)) { - SETS; + SETQ; op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; } result = op1 + op2d; if (AddOverflow(op1, op2d, result)) { - SETS; + SETQ; result = POS (result) ? 0x80000000 : 0x7fffffff; } @@ -1993,7 +1999,7 @@ mainswitch: /* CMPP reg. */ #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else rhs = DPRegRHS; temp = LHS - rhs; @@ -2047,13 +2053,13 @@ mainswitch: ARMword result; if (AddOverflow(op2, op2, op2d)) { - SETS; + SETQ; op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; } result = op1 - op2d; if (SubOverflow(op1, op2d, result)) { - SETS; + SETQ; result = POS (result) ? 0x80000000 : 0x7fffffff; } @@ -2112,7 +2118,7 @@ mainswitch: if (DESTReg == 15) { #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else rhs = DPRegRHS; temp = LHS + rhs; @@ -2200,17 +2206,57 @@ mainswitch: Handle_Store_Double (state, instr); break; } + if (BITS(4, 11) == 0xF9) { //strexd + u32 l = LHSReg; + + bool enter = false; + + if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&& + state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4)) + enter = true; + + + //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html + + + if (enter) { + ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]); + ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]); + state->Reg[DESTReg] = 0; + } else { + state->Reg[DESTReg] = 1; + } + + break; + } #endif dest = DPRegRHS; WRITEDEST (dest); break; - case 0x1b: /* MOVS reg */ + case 0x1B: /* MOVS reg */ #ifdef MODET + /* ldrexd ichfly */ + if (BITS(0, 11) == 0xF9F) { //strexd + lhs = LHS; + + state->currentexaddr = lhs; + state->currentexval = (u32)ARMul_ReadWord(state, lhs); + state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4); + + state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs); + state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4); + break; + } + if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, write-back, up, pre indexed. */ LHPREUPWB (); /* Continue with remaining instruction decoding. */ + + + + #endif dest = DPSRegRHS; WRITESDEST (dest); @@ -2297,12 +2343,12 @@ mainswitch: if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true; - ARMul_StoreHalfWord(state, lhs, RHS); //StoreWord(state, lhs, RHS) if (state->Aborted) { TAKEABORT; } if (enter) { + ARMul_StoreHalfWord(state, lhs, RHS); state->Reg[DESTReg] = 0; } else { state->Reg[DESTReg] = 1; @@ -2520,7 +2566,7 @@ mainswitch: /* TSTP immed. */ #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else temp = LHS & DPImmRHS; SETR15PSR (temp); @@ -2547,7 +2593,7 @@ mainswitch: /* TEQP immed. */ #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else temp = LHS ^ DPImmRHS; SETR15PSR (temp); @@ -2568,7 +2614,7 @@ mainswitch: /* CMPP immed. */ #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else temp = LHS - DPImmRHS; SETR15PSR (temp); @@ -2604,7 +2650,7 @@ mainswitch: /* CMNP immed. */ #ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); #else temp = LHS + DPImmRHS; SETR15PSR (temp); @@ -3054,27 +3100,21 @@ mainswitch: break; case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ - //ichfly PKHBT PKHTB todo check this - if ((instr & 0x70) == 0x10) //pkhbt - { + if ((instr & 0x70) == 0x10) { //pkhbt u8 idest = BITS(12, 15); u8 rfis = BITS(16, 19); u8 rlast = BITS(0, 3); u8 ishi = BITS(7,11); state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); break; - } - else if ((instr & 0x70) == 0x50)//pkhtb - { - u8 idest = BITS(12, 15); - u8 rfis = BITS(16, 19); - u8 rlast = BITS(0, 3); - u8 ishi = BITS(7, 11); - if (ishi == 0)ishi = 0x20; - state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000); + } else if ((instr & 0x70) == 0x50) { //pkhtb + u8 rd_idx = BITS(12, 15); + u8 rn_idx = BITS(16, 19); + u8 rm_idx = BITS(0, 3); + u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31; + state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000); break; - } - else if (BIT (4)) { + } else if (BIT (4)) { #ifdef MODE32 if (state->is_v6 && handle_v6_insn (state, instr)) @@ -3437,7 +3477,7 @@ mainswitch: case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */ if (BIT (4)) { - DEBUG("got unhandled special breakpoint\n"); + LOG_DEBUG(Core_ARM11, "got unhandled special breakpoint"); return 1; } UNDEF_LSRBaseEQOffWb; @@ -3686,13 +3726,11 @@ mainswitch: /* Co-Processor Data Transfers. */ case 0xc4: - if ((instr & 0x0FF00FF0) == 0xC400B10) //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 - { + if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)]; state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; break; - } - else if (state->is_v5) { + } else if (state->is_v5) { /* Reading from R15 is UNPREDICTABLE. */ if (BITS (12, 15) == 15 || BITS (16, 19) == 15) ARMul_UndefInstr (state, instr); @@ -3712,22 +3750,18 @@ mainswitch: break; case 0xc5: - if ((instr & 0x00000FF0) == 0xB10) //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 - { + if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1]; state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; break; - } - else if (state->is_v5) { + } else if (state->is_v5) { /* Writes to R15 are UNPREDICATABLE. */ if (DESTReg == 15 || LHSReg == 15) ARMul_UndefInstr (state, instr); /* Is access to the coprocessor allowed ? */ - else if (!CP_ACCESS_ALLOWED(state, CPNum)) - { + else if (!CP_ACCESS_ALLOWED(state, CPNum)) { ARMul_UndefInstr(state, instr); - } - else { + } else { /* MRRC, ARMv5TE and up */ ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); break; @@ -4565,7 +4599,7 @@ out: #ifdef MODE32 if (state->Bank > 0) { state->Cpsr = state->Spsr[state->Bank]; - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); } #ifdef MODET if (TFLAG) @@ -5256,7 +5290,7 @@ L_ldm_s_makeabort: //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { state->Cpsr = GETSPSR (state->Bank); - //ARMul_CPSRAltered (state); + ARMul_CPSRAltered (state); } WriteR15 (state, PC); @@ -5639,37 +5673,29 @@ L_stm_s_takeabort: /* Attempt to emulate an ARMv6 instruction. Returns non-zero upon success. */ - static int - handle_v6_insn (ARMul_State * state, ARMword instr) { - switch (BITS (20, 27)) { - //ichfly - case 0x66: //UQSUB8 - if ((instr & 0x0FF00FF0) == 0x06600FF0) { - u32 rd = (instr >> 12) & 0xF; - u32 rm = (instr >> 16) & 0xF; - u32 rn = (instr >> 0) & 0xF; - u32 subfrom = state->Reg[rm]; - u32 tosub = state->Reg[rn]; - - u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub)); - if (b1 > (u8)(subfrom)) b1 = 0; - u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8)); - if (b2 > (u8)(subfrom >> 8)) b2 = 0; - u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16)); - if (b3 > (u8)(subfrom >> 16)) b3 = 0; - u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24)); - if (b4 > (u8)(subfrom >> 24)) b4 = 0; - state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24); - return 1; - } else { - printf("UQSUB8 decoding fail %08X",instr); - } -#if 0 + static int handle_v6_insn(ARMul_State* state, ARMword instr) { + switch (BITS(20, 27)) { case 0x03: printf ("Unhandled v6 insn: ldr\n"); break; - case 0x04: - printf ("Unhandled v6 insn: umaal\n"); + case 0x04: // UMAAL + { + const u8 rm_idx = BITS(8, 11); + const u8 rn_idx = BITS(0, 3); + const u8 rd_lo_idx = BITS(12, 15); + const u8 rd_hi_idx = BITS(16, 19); + + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; + const u32 rd_lo_val = state->Reg[rd_lo_idx]; + const u32 rd_hi_val = state->Reg[rd_hi_idx]; + + const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val; + + state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF); + state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF); + return 1; + } break; case 0x06: printf ("Unhandled v6 insn: mls/str\n"); @@ -5678,9 +5704,43 @@ L_stm_s_takeabort: printf ("Unhandled v6 insn: smi\n"); break; case 0x18: + if (BITS(4, 7) == 0x9) { + /* strex */ + u32 l = LHSReg; + u32 r = RHSReg; + u32 lhs = LHS; + + bool enter = false; + + if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; + //StoreWord(state, lhs, RHS) + if (state->Aborted) { + TAKEABORT; + } + + if (enter) { + ARMul_StoreWordS(state, lhs, RHS); + state->Reg[DESTReg] = 0; + } + else { + state->Reg[DESTReg] = 1; + } + + return 1; + } printf ("Unhandled v6 insn: strex\n"); break; case 0x19: + /* ldrex */ + if (BITS(4, 7) == 0x9) { + u32 lhs = LHS; + + state->currentexaddr = lhs; + state->currentexval = ARMul_ReadWord(state, lhs); + + LoadWord(state, instr, lhs); + return 1; + } printf ("Unhandled v6 insn: ldrex\n"); break; case 0x1a: @@ -5690,9 +5750,52 @@ L_stm_s_takeabort: printf ("Unhandled v6 insn: ldrexd\n"); break; case 0x1c: + if (BITS(4, 7) == 0x9) { + /* strexb */ + u32 lhs = LHS; + + bool enter = false; + + if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; + + BUSUSEDINCPCN; + if (state->Aborted) { + TAKEABORT; + } + + + if (enter) { + ARMul_StoreByte(state, lhs, RHS); + state->Reg[DESTReg] = 0; + } + else { + state->Reg[DESTReg] = 1; + } + + //printf("In %s, strexb not implemented\n", __FUNCTION__); + UNDEF_LSRBPC; + /* WRITESDEST (dest); */ + return 1; + } printf ("Unhandled v6 insn: strexb\n"); break; case 0x1d: + if ((BITS(4, 7)) == 0x9) { + /* ldrexb */ + u32 lhs = LHS; + LoadByte(state, instr, lhs, LUNSIGNED); + + state->currentexaddr = lhs; + state->currentexval = (u32)ARMul_ReadByte(state, lhs); + + //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); + //printf("ldrexb\n"); + //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); + //exit(-1); + + //printf("In %s, ldrexb not implemented\n", __FUNCTION__); + return 1; + } printf ("Unhandled v6 insn: ldrexb\n"); break; case 0x1e: @@ -5713,510 +5816,801 @@ L_stm_s_takeabort: case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break; -#endif - case 0x61: - if ((instr & 0xFF0) == 0xf70)//ssub16 - { - u8 tar = BITS(12, 15); - u8 src1 = BITS(16, 19); - u8 src2 = BITS(0, 3); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = (state->Reg[src2] & 0xFFFF); - s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = (a1 - a2)&0xFFFF | (((b1 - b2)&0xFFFF)<< 0x10); - return 1; - } - else if ((instr & 0xFF0) == 0xf10)//sadd16 + case 0x61: // SADD16, SASX, SSAX, and SSUB16 + if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 || + (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70) { - u8 tar = BITS(12, 15); - u8 src1 = BITS(16, 19); - u8 src2 = BITS(0, 3); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = (state->Reg[src2] & 0xFFFF); - s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = (a1 + a2)&0xFFFF | (((b1 + b2)&0xFFFF)<< 0x10); + const u8 rd_idx = BITS(12, 15); + const u8 rm_idx = BITS(0, 3); + const u8 rn_idx = BITS(16, 19); + const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); + const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF); + const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); + const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF); + + s32 lo_result; + s32 hi_result; + + // SADD16 + if ((instr & 0xFF0) == 0xf10) { + lo_result = (rn_lo + rm_lo); + hi_result = (rn_hi + rm_hi); + } + // SASX + else if ((instr & 0xFF0) == 0xf30) { + lo_result = (rn_lo - rm_hi); + hi_result = (rn_hi + rm_lo); + } + // SSAX + else if ((instr & 0xFF0) == 0xf50) { + lo_result = (rn_lo + rm_hi); + hi_result = (rn_hi - rm_lo); + } + // SSUB16 + else { + lo_result = (rn_lo - rm_lo); + hi_result = (rn_hi - rm_hi); + } + + state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); + + if (lo_result >= 0) { + state->GEFlag |= (1 << 16); + state->GEFlag |= (1 << 17); + } else { + state->GEFlag &= ~(1 << 16); + state->GEFlag &= ~(1 << 17); + } + + if (hi_result >= 0) { + state->GEFlag |= (1 << 18); + state->GEFlag |= (1 << 19); + } else { + state->GEFlag &= ~(1 << 18); + state->GEFlag &= ~(1 << 19); + } + return 1; } - else if ((instr & 0xFF0) == 0xf50)//ssax + // SADD8/SSUB8 + else if ((instr & 0xFF0) == 0xf90 || (instr & 0xFF0) == 0xff0) { - u8 tar = BITS(12, 15); - u8 src1 = BITS(16, 19); - u8 src2 = BITS(0, 3); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = (state->Reg[src2] & 0xFFFF); - s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = (a1 - b2) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); + const u8 rd_idx = BITS(12, 15); + const u8 rm_idx = BITS(0, 3); + const u8 rn_idx = BITS(16, 19); + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; + + u8 lo_val1; + u8 lo_val2; + u8 hi_val1; + u8 hi_val2; + + // SADD8 + if ((instr & 0xFF0) == 0xf90) { + lo_val1 = (u8)((rn_val & 0xFF) + (rm_val & 0xFF)); + lo_val2 = (u8)(((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF)); + hi_val1 = (u8)(((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF)); + hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF)); + + if (lo_val1 & 0x80) + state->GEFlag |= (1 << 16); + else + state->GEFlag &= ~(1 << 16); + + if (lo_val2 & 0x80) + state->GEFlag |= (1 << 17); + else + state->GEFlag &= ~(1 << 17); + + if (hi_val1 & 0x80) + state->GEFlag |= (1 << 18); + else + state->GEFlag &= ~(1 << 18); + + if (hi_val2 & 0x80) + state->GEFlag |= (1 << 19); + else + state->GEFlag &= ~(1 << 19); + } + // SSUB8 + else { + lo_val1 = (u8)((rn_val & 0xFF) - (rm_val & 0xFF)); + lo_val2 = (u8)(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF)); + hi_val1 = (u8)(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF)); + hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF)); + + if (!(lo_val1 & 0x80)) + state->GEFlag |= (1 << 16); + else + state->GEFlag &= ~(1 << 16); + + if (!(lo_val2 & 0x80)) + state->GEFlag |= (1 << 17); + else + state->GEFlag &= ~(1 << 17); + + if (!(hi_val1 & 0x80)) + state->GEFlag |= (1 << 18); + else + state->GEFlag &= ~(1 << 18); + + if (!(hi_val2 & 0x80)) + state->GEFlag |= (1 << 19); + else + state->GEFlag &= ~(1 << 19); + } + + state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24); return 1; } - else if ((instr & 0xFF0) == 0xf30)//sasx - { - u8 tar = BITS(12, 15); - u8 src1 = BITS(16, 19); - u8 src2 = BITS(0, 3); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = (state->Reg[src2] & 0xFFFF); - s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = (a2 - b1) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); - return 1; + else { + printf("Unhandled v6 insn: %08x", instr); } - else printf ("Unhandled v6 insn: sadd/ssub\n"); break; - case 0x62: - if ((instr & 0xFF0) == 0xf70)//QSUB16 + case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8 { - u8 tar = BITS(12, 15); - u8 src1 = BITS(16, 19); - u8 src2 = BITS(0, 3); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = (state->Reg[src2] & 0xFFFF); - s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); - s32 res1 = (a1 - b1); - s32 res2 = (a2 - b2); - if (res1 > 0x7FFF) res1 = 0x7FFF; - if (res2 > 0x7FFF) res2 = 0x7FFF; - if (res1 < 0x7FFF) res1 = -0x8000; - if (res2 < 0x7FFF) res2 = -0x8000; - state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); - return 1; - } - else if ((instr & 0xFF0) == 0xf10)//QADD16 - { - u8 tar = BITS(12, 15); - u8 src1 = BITS(16, 19); - u8 src2 = BITS(0, 3); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = (state->Reg[src2] & 0xFFFF); - s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); - s32 res1 = (a1 + b1); - s32 res2 = (a2 + b2); - if (res1 > 0x7FFF) res1 = 0x7FFF; - if (res2 > 0x7FFF) res2 = 0x7FFF; - if (res1 < 0x7FFF) res1 = -0x8000; - if (res2 < 0x7FFF) res2 = -0x8000; - state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); + const u8 op2 = BITS(5, 7); + + const u8 rd_idx = BITS(12, 15); + const u8 rn_idx = BITS(16, 19); + const u8 rm_idx = BITS(0, 3); + const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); + const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF); + const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); + const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF); + + u16 lo_result = 0; + u16 hi_result = 0; + + // QADD16 + if (op2 == 0x00) { + lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); + hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); + } + // QASX + else if (op2 == 0x01) { + lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); + hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); + } + // QSAX + else if (op2 == 0x02) { + lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); + hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); + } + // QSUB16 + else if (op2 == 0x03) { + lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); + hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); + } + // QADD8 + else if (op2 == 0x04) { + lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | + ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; + hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | + ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; + } + // QSUB8 + else if (op2 == 0x07) { + lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | + ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; + hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | + ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; + } + + state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); return 1; } - else printf ("Unhandled v6 insn: qadd/qsub\n"); break; -#if 0 case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break; case 0x65: - printf ("Unhandled v6 insn: uadd/usub\n"); - break; - case 0x66: - printf ("Unhandled v6 insn: uqadd/uqsub\n"); - break; - case 0x67: - printf ("Unhandled v6 insn: uhadd/uhsub\n"); - break; - case 0x68: - printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); - break; -#endif - case 0x6c: - if ((instr & 0xf03f0) == 0xf0070) //uxtb16 - { - u8 src1 = BITS(0, 3); - u8 tar = BITS(12, 15); - u32 base = state->Reg[src1]; - u32 shamt = BITS(9,10)* 8; - u32 in = ((base << (32 - shamt)) | (base >> shamt)); - state->Reg[tar] = in & 0x00FF00FF; - return 1; - } - else - printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); - break; - case 0x70: - if ((instr & 0xf0d0) == 0xf010)//smuad //ichfly - { - u8 tar = BITS(16, 19); - u8 src1 = BITS(0, 3); - u8 src2 = BITS(8, 11); - u8 swap = BIT(5); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); - s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = a1*a2 + b1*b2; - return 1; + { + u32 rd = (instr >> 12) & 0xF; + u32 rn = (instr >> 16) & 0xF; + u32 rm = (instr >> 0) & 0xF; + u32 from = state->Reg[rn]; + u32 to = state->Reg[rm]; + + if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16 + u32 h1, h2; + state->Cpsr &= 0xfff0ffff; + if ((instr & 0x0F0) == 0x070) { // USUB16 + h1 = ((u16)from - (u16)to); + h2 = ((u16)(from >> 16) - (u16)(to >> 16)); + + if (!(h1 & 0xffff0000)) + state->GEFlag |= (3 << 16); + else + state->GEFlag &= ~(3 << 16); - } - else if ((instr & 0xf0d0) == 0xf050)//smusd - { - u8 tar = BITS(16, 19); - u8 src1 = BITS(0, 3); - u8 src2 = BITS(8, 11); - u8 swap = BIT(5); - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); - s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = a1*a2 - b1*b2; - return 1; - } - else if ((instr & 0xd0) == 0x10)//smlad - { - u8 tar = BITS(16, 19); - u8 src1 = BITS(0, 3); - u8 src2 = BITS(8, 11); - u8 src3 = BITS(12, 15); - u8 swap = BIT(5); - - u32 a3 = state->Reg[src3]; - - s16 a1 = (state->Reg[src1] & 0xFFFF); - s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); - s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); - s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); - state->Reg[tar] = a1*a2 + b1*b2 + a3; + if (!(h2 & 0xffff0000)) + state->GEFlag |= (3 << 18); + else + state->GEFlag &= ~(3 << 18); + } + else { // UADD16 + h1 = ((u16)from + (u16)to); + h2 = ((u16)(from >> 16) + (u16)(to >> 16)); + + if (h1 & 0xffff0000) + state->GEFlag |= (3 << 16); + else + state->GEFlag &= ~(3 << 16); + + if (h2 & 0xffff0000) + state->GEFlag |= (3 << 18); + else + state->GEFlag &= ~(3 << 18); + } + + state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); return 1; } - else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); - break; - case 0x74: - printf ("Unhandled v6 insn: smlald/smlsld\n"); - break; - case 0x75: - printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); - break; - case 0x78: - printf ("Unhandled v6 insn: usad/usada8\n"); - break; -#if 0 - case 0x7a: - printf ("Unhandled v6 insn: usbfx\n"); - break; - case 0x7c: - printf ("Unhandled v6 insn: bfc/bfi\n"); - break; -#endif + else + if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8 + u32 b1, b2, b3, b4; + state->Cpsr &= 0xfff0ffff; + if ((instr & 0x0F0) == 0x0F0) { // USUB8 + b1 = ((u8)from - (u8)to); + b2 = ((u8)(from >> 8) - (u8)(to >> 8)); + b3 = ((u8)(from >> 16) - (u8)(to >> 16)); + b4 = ((u8)(from >> 24) - (u8)(to >> 24)); + + if (!(b1 & 0xffffff00)) + state->GEFlag |= (1 << 16); + else + state->GEFlag &= ~(1 << 16); + if (!(b2 & 0xffffff00)) + state->GEFlag |= (1 << 17); + else + state->GEFlag &= ~(1 << 17); - /* add new instr for arm v6. */ - ARMword lhs, temp; - case 0x18: { /* ORR reg */ - /* dyf add armv6 instr strex 2010.9.17 */ - if (BITS (4, 7) == 0x9) { - u32 l = LHSReg; - u32 r = RHSReg; - lhs = LHS; + if (!(b3 & 0xffffff00)) + state->GEFlag |= (1 << 18); + else + state->GEFlag &= ~(1 << 18); - bool enter = false; + if (!(b4 & 0xffffff00)) + state->GEFlag |= (1 << 19); + else + state->GEFlag &= ~(1 << 19); + } + else { // UADD8 + b1 = ((u8)from + (u8)to); + b2 = ((u8)(from >> 8) + (u8)(to >> 8)); + b3 = ((u8)(from >> 16) + (u8)(to >> 16)); + b4 = ((u8)(from >> 24) + (u8)(to >> 24)); - if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; - ARMul_StoreWordS(state, lhs, RHS); - //StoreWord(state, lhs, RHS) - if (state->Aborted) { - TAKEABORT; - } + if (b1 & 0xffffff00) + state->GEFlag |= (1 << 16); + else + state->GEFlag &= ~(1 << 16); - if (enter) { - state->Reg[DESTReg] = 0; - } else { - state->Reg[DESTReg] = 1; - } + if (b2 & 0xffffff00) + state->GEFlag |= (1 << 17); + else + state->GEFlag &= ~(1 << 17); - return 1; - } - break; - } + if (b3 & 0xffffff00) + state->GEFlag |= (1 << 18); + else + state->GEFlag &= ~(1 << 18); - case 0x19: { /* orrs reg */ - /* dyf add armv6 instr ldrex */ - if (BITS (4, 7) == 0x9) { - lhs = LHS; + if (b4 & 0xffffff00) + state->GEFlag |= (1 << 19); + else + state->GEFlag &= ~(1 << 19); + } - state->currentexaddr = lhs; - state->currentexval = ARMul_ReadWord(state, lhs); + state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); + return 1; + } + } + printf("Unhandled v6 insn: uasx/usax\n"); + break; + case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8 + { + const u8 rd_idx = BITS(12, 15); + const u8 rm_idx = BITS(0, 3); + const u8 rn_idx = BITS(16, 19); + const u8 op2 = BITS(5, 7); + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; + + u16 lo_val = 0; + u16 hi_val = 0; + + // UQADD16 + if (op2 == 0x00) { + lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + } + // UQASX + else if (op2 == 0x01) { + lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + } + // UQSAX + else if (op2 == 0x02) { + lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + } + // UQSUB16 + else if (op2 == 0x03) { + lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + } + // UQADD8 + else if (op2 == 0x04) { + lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | + ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; + hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | + ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; + } + // UQSUB8 + else { + lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | + ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; + hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | + ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; + } - LoadWord (state, instr, lhs); + state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16); return 1; } break; - } + case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8. + { + const u8 op2 = BITS(5, 7); - case 0x1c: { /* BIC reg */ - /* dyf add for STREXB */ - if (BITS (4, 7) == 0x9) { - lhs = LHS; + const u8 rm_idx = BITS(0, 3); + const u8 rn_idx = BITS(16, 19); + const u8 rd_idx = BITS(12, 15); - bool enter = false; + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; - if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; + if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) + { + u32 lo_val = 0; + u32 hi_val = 0; - ARMul_StoreByte (state, lhs, RHS); - BUSUSEDINCPCN; - if (state->Aborted) { - TAKEABORT; - } + // UHADD16 + if (op2 == 0x00) { + lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + } + // UHASX + else if (op2 == 0x01) { + lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); + } + // UHSAX + else if (op2 == 0x02) { + lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); + } + // UHSUB16 + else if (op2 == 0x03) { + lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + } + lo_val >>= 1; + hi_val >>= 1; - if (enter) { - state->Reg[DESTReg] = 0; - } else { - state->Reg[DESTReg] = 1; + state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); + return 1; + } + else if (op2 == 0x04 || op2 == 0x07) { + u32 sum1; + u32 sum2; + u32 sum3; + u32 sum4; + + // UHADD8 + if (op2 == 0x04) { + sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); + sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); + sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); + sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); + } + // UHSUB8 + else { + sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); + sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); + sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); + sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); + } + + sum1 >>= 1; + sum2 >>= 1; + sum3 >>= 1; + sum4 >>= 1; + + state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); + return 1; } - - //printf("In %s, strexb not implemented\n", __FUNCTION__); - UNDEF_LSRBPC; - /* WRITESDEST (dest); */ - return 1; } break; + case 0x68: + { + u32 rd = (instr >> 12) & 0xF; + u32 rn = (instr >> 16) & 0xF; + u32 rm = (instr >> 0) & 0xF; + u32 from = state->Reg[rn]; + u32 to = state->Reg[rm]; + u32 cpsr = ARMul_GetCPSR(state); + if ((instr & 0xFF0) == 0xFB0) { // SEL + u32 result; + if (cpsr & (1 << 16)) + result = from & 0xff; + else + result = to & 0xff; + if (cpsr & (1 << 17)) + result |= from & 0x0000ff00; + else + result |= to & 0x0000ff00; + if (cpsr & (1 << 18)) + result |= from & 0x00ff0000; + else + result |= to & 0x00ff0000; + if (cpsr & (1 << 19)) + result |= from & 0xff000000; + else + result |= to & 0xff000000; + state->Reg[rd] = result; + return 1; + } } + printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); + break; + + case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB + { + const u8 op2 = BITS(5, 7); + + // SSAT16 + if (op2 == 0x01) { + const u8 rd_idx = BITS(12, 15); + const u8 rn_idx = BITS(0, 3); + const u8 num_bits = BITS(16, 19) + 1; + const s16 min = -(0x8000 >> (16 - num_bits)); + const s16 max = (0x7FFF >> (16 - num_bits)); + s16 rn_lo = (state->Reg[rn_idx]); + s16 rn_hi = (state->Reg[rn_idx] >> 16); + + if (rn_lo > max) { + rn_lo = max; + SETQ; + } else if (rn_lo < min) { + rn_lo = min; + SETQ; + } + + if (rn_hi > max) { + rn_hi = max; + SETQ; + } else if (rn_hi < min) { + rn_hi = min; + SETQ; + } + + state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16); + return 1; + } + else if (op2 == 0x03) { + const u8 rotation = BITS(10, 11) * 8; + u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF); + if (rm & 0x80) + rm |= 0xffffff00; + + // SXTB, otherwise SXTAB + if (BITS(16, 19) == 0xf) + state->Reg[BITS(12, 15)] = rm; + else + state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; + + return 1; + } + else { + printf("Unimplemented op: SSAT"); + } + } + break; + + case 0x6b: // REV, REV16, SXTH, and SXTAH + { + const u8 op2 = BITS(5, 7); + + // REV + if (op2 == 0x01) { + DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); + return 1; + } + // REV16 + else if (op2 == 0x05) { + DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); + return 1; + } + else if (op2 == 0x03) { + const u8 rotate = BITS(10, 11) * 8; + + u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF); + if (rm & 0x8000) + rm |= 0xffff0000; + + // SXTH, otherwise SXTAH + if (BITS(16, 19) == 15) + state->Reg[BITS(12, 15)] = rm; + else + state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; + + return 1; + } + } + break; + + case 0x6c: // UXTB16 and UXTAB16 + { + const u8 rm_idx = BITS(0, 3); + const u8 rn_idx = BITS(16, 19); + const u8 rd_idx = BITS(12, 15); + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; + const u32 rotation = BITS(10, 11) * 8; + const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); + + // UXTB16 + if ((instr & 0xf03f0) == 0xf0070) { + state->Reg[rd_idx] = rotated_rm & 0x00FF00FF; + } + else { // UXTAB16 + const u8 lo_rotated = (rotated_rm & 0xFF); + const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; + + const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; + const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; + + state->Reg[rd_idx] = ((hi_result << 16) | (lo_result & 0xFFFF)); + } + + return 1; + } + break; + case 0x6e: // USAT, USAT16, UXTB, and UXTAB + { + const u8 op2 = BITS(5, 7); + + // USAT16 + if (op2 == 0x01) { + const u8 rd_idx = BITS(12, 15); + const u8 rn_idx = BITS(0, 3); + const u8 num_bits = BITS(16, 19); + const s16 max = 0xFFFF >> (16 - num_bits); + s16 rn_lo = (state->Reg[rn_idx]); + s16 rn_hi = (state->Reg[rn_idx] >> 16); + + if (max < rn_lo) { + rn_lo = max; + SETQ; + } else if (rn_lo < 0) { + rn_lo = 0; + SETQ; + } + + if (max < rn_hi) { + rn_hi = max; + SETQ; + } else if (rn_hi < 0) { + rn_hi = 0; + SETQ; + } + + state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); + return 1; + } + else if (op2 == 0x03) { + const u8 rotate = BITS(10, 11) * 8; + const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF); + + if (BITS(16, 19) == 0xf) + /* UXTB */ + state->Reg[BITS(12, 15)] = rm; + else + /* UXTAB */ + state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; + + return 1; + } + else { + printf("Unimplemented op: USAT"); + } + } + break; + + case 0x6f: // UXTH, UXTAH, and REVSH. + { + const u8 op2 = BITS(5, 7); + + // REVSH + if (op2 == 0x05) { + DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8); + if (DEST & 0x8000) + DEST |= 0xffff0000; + return 1; + } + // UXTH and UXTAH + else if (op2 == 0x03) { + const u8 rotate = BITS(10, 11) * 8; + const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF); + + // UXTH + if (BITS(16, 19) == 0xf) { + state->Reg[BITS(12, 15)] = rm; + } + // UXTAH + else { + state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; + } + + return 1; + } + } + case 0x70: + // ichfly + // SMUAD, SMUSD, SMLAD, and SMLSD + if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 || + (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50) + { + const u8 rd_idx = BITS(16, 19); + const u8 rn_idx = BITS(0, 3); + const u8 rm_idx = BITS(8, 11); + const u8 ra_idx = BITS(12, 15); + const bool do_swap = (BIT(5) == 1); - case 0x1d: { /* BICS reg */ - if ((BITS (4, 7)) == 0x9) { - /* ldrexb */ - temp = LHS; - LoadByte (state, instr, temp, LUNSIGNED); + u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; - state->currentexaddr = temp; - state->currentexval = (u32)ARMul_ReadByte(state, temp); + if (do_swap) + rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); - //printf("ldrexb\n"); - //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); - //exit(-1); + 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); - //printf("In %s, ldrexb not implemented\n", __FUNCTION__); - return 1; - } - break; - } - /* add end */ + const u32 product1 = (rn_lo * rm_lo); + const u32 product2 = (rn_hi * rm_hi); - case 0x6a: { - ARMword Rm; - int ror = -1; + // SMUAD and SMLAD + if (BIT(6) == 0) { + state->Reg[rd_idx] = product1 + product2; - switch (BITS (4, 11)) { - case 0x07: - ror = 0; - break; - case 0x47: - ror = 8; - break; - case 0x87: - ror = 16; - break; - case 0xc7: - ror = 24; - break; + if (BITS(12, 15) != 15) { + state->Reg[rd_idx] += state->Reg[ra_idx]; + ARMul_AddOverflowQ(state, product1 + product2, state->Reg[ra_idx]); + } - case 0x01: - case 0xf3: - //ichfly - //SSAT16 - { - u8 tar = BITS(12,15); - u8 src = BITS(0, 3); - u8 val = BITS(16, 19) + 1; - s16 a1 = (state->Reg[src]); - s16 a2 = (state->Reg[src] >> 0x10); - s16 min = (s16)(0x8000) >> (16 - val); - s16 max = 0x7FFF >> (16 - val); - if (min > a1) a1 = min; - if (max < a1) a1 = max; - if (min > a2) a2 = min; - if (max < a2) a2 = max; - u32 temp2 = ((u32)(a2)) << 0x10; - state->Reg[tar] = (a1&0xFFFF) | (temp2); - } + ARMul_AddOverflowQ(state, product1, product2); + } + // SMUSD and SMLSD + else { + state->Reg[rd_idx] = product1 - product2; + + if (BITS(12, 15) != 15) + state->Reg[rd_idx] += state->Reg[ra_idx]; + } return 1; - default: - break; } - - if (ror == -1) { - if (BITS (4, 6) == 0x7) { - printf ("Unhandled v6 insn: ssat\n"); - return 0; + break; + case 0x74: // SMLALD and SMLSLD + { + const u8 rm_idx = BITS(8, 11); + const u8 rn_idx = BITS(0, 3); + const u8 rdlo_idx = BITS(12, 15); + const u8 rdhi_idx = BITS(16, 19); + const bool do_swap = (BIT(5) == 1); + + const u32 rdlo_val = state->Reg[rdlo_idx]; + const u32 rdhi_val = state->Reg[rdhi_idx]; + const u32 rn_val = state->Reg[rn_idx]; + u32 rm_val = state->Reg[rm_idx]; + + 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(6) == 0) { + result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); + } + // SMLSLD + else { + result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); } - break; - } - - Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); - if (Rm & 0x80) - Rm |= 0xffffff00; - - if (BITS (16, 19) == 0xf) - /* SXTB */ - state->Reg[BITS (12, 15)] = Rm; - else - /* SXTAB */ - state->Reg[BITS (12, 15)] += Rm; - } - return 1; - - case 0x6b: { - ARMword Rm; - int ror = -1; - - switch (BITS (4, 11)) { - case 0x07: - ror = 0; - break; - case 0x47: - ror = 8; - break; - case 0x87: - ror = 16; - break; - case 0xc7: - ror = 24; - break; - case 0xf3: - DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); + state->Reg[rdlo_idx] = (result & 0xFFFFFFFF); + state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF); return 1; - case 0xfb: - DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); - return 1; - default: - break; } + break; + case 0x75: // SMMLA, SMMUL, and SMMLS + { + const u8 rm_idx = BITS(8, 11); + const u8 rn_idx = BITS(0, 3); + const u8 ra_idx = BITS(12, 15); + const u8 rd_idx = BITS(16, 19); + const bool do_round = (BIT(5) == 1); - if (ror == -1) - break; + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; - Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); - if (Rm & 0x8000) - Rm |= 0xffff0000; + // Assume SMMUL by default. + s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val; - if (BITS (16, 19) == 0xf) - /* SXTH */ - state->Reg[BITS (12, 15)] = Rm; - else - /* SXTAH */ - state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; - } - return 1; + if (ra_idx != 15) { + const u32 ra_val = state->Reg[ra_idx]; - case 0x6e: { - ARMword Rm; - int ror = -1; + // SMMLA, otherwise SMMLS + if (BIT(6) == 0) + result += ((s64)ra_val << 32); + else + result = ((s64)ra_val << 32) - result; + } - switch (BITS (4, 11)) { - case 0x07: - ror = 0; - break; - case 0x47: - ror = 8; - break; - case 0x87: - ror = 16; - break; - case 0xc7: - ror = 24; - break; + if (do_round) + result += 0x80000000; - case 0x01: - case 0xf3: - //ichfly - //USAT16 - { - u8 tar = BITS(12, 15); - u8 src = BITS(0, 3); - u8 val = BITS(16, 19); - s16 a1 = (state->Reg[src]); - s16 a2 = (state->Reg[src] >> 0x10); - s16 max = 0xFFFF >> (16 - val); - if (max < a1) a1 = max; - if (max < a2) a2 = max; - u32 temp2 = ((u32)(a2)) << 0x10; - state->Reg[tar] = (a1 & 0xFFFF) | (temp2); - } + state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF); return 1; - default: - break; - } - - if (ror == -1) { - if (BITS (4, 6) == 0x7) { - printf ("Unhandled v6 insn: usat\n"); - return 0; - } - break; } + break; + case 0x78: + if (BITS(20, 24) == 0x18) + { + const u8 rm_idx = BITS(8, 11); + const u8 rn_idx = BITS(0, 3); + const u8 rd_idx = BITS(16, 19); - Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); - - if (BITS (16, 19) == 0xf) - /* UXTB */ - state->Reg[BITS (12, 15)] = Rm; - else - /* UXTAB */ - state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; - } - return 1; + const u32 rm_val = state->Reg[rm_idx]; + const u32 rn_val = state->Reg[rn_idx]; - case 0x6f: { - ARMword Rm; - int ror = -1; + const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); + const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); + const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); + const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); - switch (BITS (4, 11)) { - case 0x07: - ror = 0; - break; - case 0x47: - ror = 8; - break; - case 0x87: - ror = 16; - break; - case 0xc7: - ror = 24; - break; + u32 finalDif = (diff1 + diff2 + diff3 + diff4); - case 0xfb: - printf ("Unhandled v6 insn: revsh\n"); - return 0; - default: - break; - } + // Op is USADA8 if true. + const u8 ra_idx = BITS(12, 15); + if (ra_idx != 15) + finalDif += state->Reg[ra_idx]; - if (ror == -1) - break; - - Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); - - /* UXT */ - /* state->Reg[BITS (12, 15)] = Rm; */ - /* dyf add */ - if (BITS (16, 19) == 0xf) { - state->Reg[BITS (12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF; - } else { - /* UXTAH */ - /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */ -// printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)] -// , Rm, BITS(10, 11)); -// printf("icounter is %lld\n", state->NumInstrs); - state->Reg[BITS (12, 15)] = (state->Reg[BITS (16, 19)] >> (8 * (BITS(10, 11)))) + Rm; -// printf("rd is %x\n", state->Reg[BITS (12, 15)]); -// exit(-1); + state->Reg[rd_idx] = finalDif; + return 1; } - } - return 1; - -#if 0 + break; + case 0x7a: + printf ("Unhandled v6 insn: usbfx\n"); + break; + case 0x7c: + printf ("Unhandled v6 insn: bfc/bfi\n"); + break; case 0x84: printf ("Unhandled v6 insn: srs\n"); break; -#endif default: break; } printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27)); return 0; - } + }
\ No newline at end of file diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 2568b93ef..426b67831 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -227,8 +227,9 @@ ARMul_CPSRAltered (ARMul_State * state) //state->Cpsr &= ~CBIT; ASSIGNV ((state->Cpsr & VBIT) != 0); //state->Cpsr &= ~VBIT; - ASSIGNS ((state->Cpsr & SBIT) != 0); - //state->Cpsr &= ~SBIT; + ASSIGNQ ((state->Cpsr & QBIT) != 0); + //state->Cpsr &= ~QBIT; + state->GEFlag = (state->Cpsr & 0x000F0000); #ifdef MODET ASSIGNT ((state->Cpsr & TBIT) != 0); //state->Cpsr &= ~TBIT; @@ -391,6 +392,15 @@ ARMul_NthReg (ARMword instr, unsigned number) return (bit - 1); } +/* Unsigned sum of absolute difference */ +u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) +{ + if (left > right) + return left - right; + + return right - left; +} + /* Assigns the N and Z flags depending on the value of result. */ void @@ -443,6 +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) +{ + u32 result = a + b; + if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) + SETQ; +} + /* Assigns the C flag after an subtraction of a and b to give result. */ void @@ -460,6 +478,142 @@ ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) ASSIGNV (SubOverflow (a, b, result)); } +/* 8-bit signed saturated addition */ +u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) +{ + u8 result = left + right; + + if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) { + if (left & 0x80) + result = 0x80; + else + result = 0x7F; + } + + return result; +} + +/* 8-bit signed saturated subtraction */ +u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) +{ + u8 result = left - right; + + if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) { + if (left & 0x80) + result = 0x80; + else + result = 0x7F; + } + + return result; +} + +/* 16-bit signed saturated addition */ +u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) +{ + u16 result = left + right; + + if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) { + if (left & 0x8000) + result = 0x8000; + else + result = 0x7FFF; + } + + return result; +} + +/* 16-bit signed saturated subtraction */ +u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) +{ + u16 result = left - right; + + if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) { + if (left & 0x8000) + result = 0x8000; + else + result = 0x7FFF; + } + + return result; +} + +/* 8-bit unsigned saturated addition */ +u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) +{ + u8 result = left + right; + + if (result < left) + result = 0xFF; + + return result; +} + +/* 16-bit unsigned saturated addition */ +u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) +{ + u16 result = left + right; + + if (result < left) + result = 0xFFFF; + + return result; +} + +/* 8-bit unsigned saturated subtraction */ +u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) +{ + if (left <= right) + return 0; + + return left - right; +} + +/* 16-bit unsigned saturated subtraction */ +u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) +{ + if (left <= right) + return 0; + + return left - right; +} + +// Signed saturation. +u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) +{ + const u32 max = (1 << shift) - 1; + const s32 top = (value >> shift); + + if (top > 0) { + *saturation_occurred = true; + return max; + } + else if (top < -1) { + *saturation_occurred = true; + return ~max; + } + + *saturation_occurred = false; + return (u32)value; +} + +// Unsigned saturation +u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) +{ + const u32 max = (1 << shift) - 1; + + if (value < 0) { + *saturation_occurred = true; + return 0; + } else if ((u32)value > max) { + *saturation_occurred = true; + return max; + } + + *saturation_occurred = false; + return (u32)value; +} + /* This function does the work of generating the addresses used in an LDC instruction. The code here is always post-indexed, it's up to the caller to get the input address correct and to handle base register @@ -665,7 +819,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) //if (!CP_ACCESS_ALLOWED (state, CPNum)) { if (!state->MCR[CPNum]) { //chy 2004-07-19 should fix in the future ????!!!! - DEBUG("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); + LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x",CPNum, source); ARMul_UndefInstr (state, instr); return; } @@ -690,7 +844,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) } if (cpab == ARMul_CANT) { - DEBUG("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); //ichfly todo + LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x", instr, CPNum, source); //ichfly todo //ARMul_Abort (state, ARMul_UndefinedInstrV); } else { BUSUSEDINCPCN; @@ -762,7 +916,7 @@ ARMword ARMul_MRC (ARMul_State * state, ARMword instr) //if (!CP_ACCESS_ALLOWED (state, CPNum)) { if (!state->MRC[CPNum]) { //chy 2004-07-19 should fix in the future????!!!! - DEBUG("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n", CPNum, instr); + LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x", CPNum, instr); ARMul_UndefInstr (state, instr); return -1; } @@ -865,7 +1019,7 @@ void ARMul_UndefInstr (ARMul_State * state, ARMword instr) { std::string disasm = ARM_Disasm::Disassemble(state->pc, instr); - ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); + LOG_ERROR(Core_ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); ARMul_Abort (state, ARMul_UndefinedInstrV); } diff --git a/src/core/arm/interpreter/thumbemu.cpp b/src/core/arm/interpreter/thumbemu.cpp index f7f11f714..9cf80672d 100644 --- a/src/core/arm/interpreter/thumbemu.cpp +++ b/src/core/arm/interpreter/thumbemu.cpp @@ -467,7 +467,7 @@ ARMul_ThumbDecode ( (state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; state->Reg[14] = (tmp | 1); CLEART; - DEBUG_LOG(ARM11, "In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1); + LOG_DEBUG(Core_ARM11, "After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x", state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1); valid = t_branch; FLUSHPIPE; } diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 8343aaa01..8611d7392 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -18,38 +18,26 @@ #ifndef _ARMDEFS_H_ #define _ARMDEFS_H_ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#include "common/platform.h" - -//teawater add for arm2x86 2005.02.14------------------------------------------- -// koodailar remove it for mingw 2005.12.18---------------- -//anthonylee modify it for portable 2007.01.30 -//#include "portable/mman.h" +#include <cerrno> +#include <csignal> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> #include "arm_regformat.h" +#include "common/common_types.h" #include "common/platform.h" +#include "core/arm/skyeye_common/armmmu.h" #include "core/arm/skyeye_common/skyeye_defs.h" -//AJ2D-------------------------------------------------------------------------- - -//teawater add for arm2x86 2005.07.03------------------------------------------- - -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #if EMU_PLATFORM == PLATFORM_LINUX +#include <sys/time.h> #include <unistd.h> #endif -#include <errno.h> -#include <sys/stat.h> -#include <fcntl.h> -//#include <memory_space.h> -//AJ2D-------------------------------------------------------------------------- #if 0 #if 0 #define DIFF_STATE 1 @@ -70,25 +58,8 @@ #define LOWHIGH 1 #define HIGHLOW 2 -//teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- -#include <signal.h> - -#include "common/platform.h" - -#if EMU_PLATFORM == PLATFORM_LINUX -#include <sys/time.h> -#endif - //#define DBCT_TEST_SPEED #define DBCT_TEST_SPEED_SEC 10 -//AJ2D-------------------------------------------------------------------------- - -//teawater add compile switch for DBCT GDB RSP function 2005.10.21-------------- -//#define DBCT_GDBRSP -//AJ2D-------------------------------------------------------------------------- - -//#include <skyeye_defs.h> -//#include <skyeye_types.h> #define ARM_BYTE_TYPE 0 #define ARM_HALFWORD_TYPE 1 @@ -103,71 +74,34 @@ typedef char *VoidStar; #endif -typedef unsigned long long ARMdword; /* must be 64 bits wide */ -typedef unsigned int ARMword; /* must be 32 bits wide */ -typedef unsigned char ARMbyte; /* must be 8 bits wide */ -typedef unsigned short ARMhword; /* must be 16 bits wide */ +typedef u64 ARMdword; // must be 64 bits wide +typedef u32 ARMword; // must be 32 bits wide +typedef u16 ARMhword; // must be 16 bits wide +typedef u8 ARMbyte; // must be 8 bits wide typedef struct ARMul_State ARMul_State; typedef struct ARMul_io ARMul_io; typedef struct ARMul_Energy ARMul_Energy; -//teawater add for arm2x86 2005.06.24------------------------------------------- -#include <stdint.h> -//AJ2D-------------------------------------------------------------------------- -/* -//chy 2005-05-11 -#ifndef __CYGWIN__ -//teawater add for arm2x86 2005.02.14------------------------------------------- -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int u32; -#if defined (__x86_64__) -typedef unsigned long uint64_t; -#else -typedef unsigned long long uint64_t; -#endif -////AJ2D-------------------------------------------------------------------------- -#endif -*/ -#include "core/arm/skyeye_common/armmmu.h" -//#include "lcd/skyeye_lcd.h" - - -//#include "skyeye.h" -//#include "skyeye_device.h" -//#include "net/skyeye_net.h" -//#include "skyeye_config.h" - - -typedef unsigned ARMul_CPInits (ARMul_State * state); -typedef unsigned ARMul_CPExits (ARMul_State * state); -typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type, - ARMword instr, ARMword value); -typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type, - ARMword instr, ARMword * value); -typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type, - ARMword instr, ARMword * value); -typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type, - ARMword instr, ARMword value); -typedef unsigned ARMul_MRRCs (ARMul_State * state, unsigned type, - ARMword instr, ARMword * value1, ARMword * value2); -typedef unsigned ARMul_MCRRs (ARMul_State * state, unsigned type, - ARMword instr, ARMword value1, ARMword value2); -typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type, - ARMword instr); -typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg, - ARMword * value); -typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg, - ARMword value); +typedef unsigned ARMul_CPInits(ARMul_State* state); +typedef unsigned ARMul_CPExits(ARMul_State* state); +typedef unsigned ARMul_LDCs(ARMul_State* state, unsigned type, ARMword instr, ARMword value); +typedef unsigned ARMul_STCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value); +typedef unsigned ARMul_MRCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value); +typedef unsigned ARMul_MCRs(ARMul_State* state, unsigned type, ARMword instr, ARMword value); +typedef unsigned ARMul_MRRCs(ARMul_State* state, unsigned type, ARMword instr, ARMword* value1, ARMword* value2); +typedef unsigned ARMul_MCRRs(ARMul_State* state, unsigned type, ARMword instr, ARMword value1, ARMword value2); +typedef unsigned ARMul_CDPs(ARMul_State* state, unsigned type, ARMword instr); +typedef unsigned ARMul_CPReads(ARMul_State* state, unsigned reg, ARMword* value); +typedef unsigned ARMul_CPWrites(ARMul_State* state, unsigned reg, ARMword value); //added by ksh,2004-3-5 struct ARMul_io { - ARMword *instr; //to display the current interrupt state - ARMword *net_flag; //to judge if network is enabled - ARMword *net_int; //netcard interrupt + ARMword *instr; // to display the current interrupt state + ARMword *net_flag; // to judge if network is enabled + ARMword *net_int; // netcard interrupt //ywc,2004-04-01 ARMword *ts_int; @@ -180,17 +114,17 @@ struct ARMul_io /* added by ksh,2004-11-26,some energy profiling */ struct ARMul_Energy { - int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */ - int enable_func_energy; /* <tktan> BUG200105181702 */ + int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */ + int enable_func_energy; /* <tktan> BUG200105181702 */ char *func_energy; - int func_display; /* <tktan> BUG200103311509 : for function call display */ + int func_display; /* <tktan> BUG200103311509 : for function call display */ int func_disp_start; /* <tktan> BUG200104191428 : to start func profiling */ - char *start_func; /* <tktan> BUG200104191428 */ + char *start_func; /* <tktan> BUG200104191428 */ - FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */ + FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */ long long tcycle, pcycle; float t_energy; - void *cur_task; /* <tktan> BUG200103291737 */ + void *cur_task; /* <tktan> BUG200103291737 */ long long t_mem_cycle, t_idle_cycle, t_uart_cycle; long long p_mem_cycle, p_idle_cycle, p_uart_cycle; long long p_io_update_tcycle; @@ -203,13 +137,12 @@ struct ARMul_Energy typedef struct mem_bank { - ARMword (*read_byte) (ARMul_State * state, ARMword addr); - void (*write_byte) (ARMul_State * state, ARMword addr, ARMword data); - ARMword (*read_halfword) (ARMul_State * state, ARMword addr); - void (*write_halfword) (ARMul_State * state, ARMword addr, - ARMword data); - ARMword (*read_word) (ARMul_State * state, ARMword addr); - void (*write_word) (ARMul_State * state, ARMword addr, ARMword data); + ARMword (*read_byte) (ARMul_State* state, ARMword addr); + void (*write_byte) (ARMul_State* state, ARMword addr, ARMword data); + ARMword (*read_halfword) (ARMul_State* state, ARMword addr); + void (*write_halfword) (ARMul_State* state, ARMword addr, ARMword data); + ARMword (*read_word) (ARMul_State* state, ARMword addr); + void (*write_word) (ARMul_State* state, ARMword addr, ARMword data); unsigned int addr, len; char filename[MAX_STR]; unsigned type; //chy 2003-09-21: maybe io,ram,rom @@ -224,24 +157,24 @@ typedef struct #define VFP_REG_NUM 64 struct ARMul_State { - ARMword Emulate; /* to start and stop emulation */ - unsigned EndCondition; /* reason for stopping */ + ARMword Emulate; /* to start and stop emulation */ + unsigned EndCondition; /* reason for stopping */ unsigned ErrorCode; /* type of illegal instruction */ /* Order of the following register should not be modified */ - ARMword Reg[16]; /* the current register file */ - ARMword Cpsr; /* the current psr */ + ARMword Reg[16]; /* the current register file */ + ARMword Cpsr; /* the current psr */ ARMword Spsr_copy; ARMword phys_pc; ARMword Reg_usr[2]; - ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ + ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ ARMword Reg_firq[7]; /* R8---R14 FIRQ */ - ARMword Spsr[7]; /* the exception psr's */ - ARMword Mode; /* the current mode */ - ARMword Bank; /* the current register bank */ + ARMword Spsr[7]; /* the exception psr's */ + ARMword Mode; /* the current mode */ + ARMword Bank; /* the current register bank */ ARMword exclusive_tag; ARMword exclusive_state; ARMword exclusive_result; @@ -265,7 +198,7 @@ struct ARMul_State //ARMword translate_pc; /* add armv6 flags dyf:2010-08-09 */ - ARMword GEFlag, EFlag, AFlag, QFlags; + ARMword GEFlag, EFlag, AFlag, QFlag; //chy:2003-08-19, used in arm v5e|xscale ARMword SFlag; #ifdef MODET @@ -281,38 +214,39 @@ struct ARMul_State ARMword currentexaddr; ARMword currentexval; + ARMword currentexvald; ARMword servaddr; unsigned NextInstr; - unsigned VectorCatch; /* caught exception mask */ - unsigned CallDebug; /* set to call the debugger */ - unsigned CanWatch; /* set by memory interface if its willing to suffer the - overhead of checking for watchpoints on each memory - access */ + unsigned VectorCatch; /* caught exception mask */ + unsigned CallDebug; /* set to call the debugger */ + unsigned CanWatch; /* set by memory interface if its willing to suffer the + overhead of checking for watchpoints on each memory + access */ unsigned int StopHandle; - char *CommandLine; /* Command Line from ARMsd */ - - ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */ - ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */ - ARMul_LDCs *LDC[16]; /* LDC instruction */ - ARMul_STCs *STC[16]; /* STC instruction */ - ARMul_MRCs *MRC[16]; /* MRC instruction */ - ARMul_MCRs *MCR[16]; /* MCR instruction */ - ARMul_MRRCs *MRRC[16]; /* MRRC instruction */ - ARMul_MCRRs *MCRR[16]; /* MCRR instruction */ - ARMul_CDPs *CDP[16]; /* CDP instruction */ - ARMul_CPReads *CPRead[16]; /* Read CP register */ - ARMul_CPWrites *CPWrite[16]; /* Write CP register */ - unsigned char *CPData[16]; /* Coprocessor data */ + char *CommandLine; /* Command Line from ARMsd */ + + ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */ + ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */ + ARMul_LDCs *LDC[16]; /* LDC instruction */ + ARMul_STCs *STC[16]; /* STC instruction */ + ARMul_MRCs *MRC[16]; /* MRC instruction */ + ARMul_MCRs *MCR[16]; /* MCR instruction */ + ARMul_MRRCs *MRRC[16]; /* MRRC instruction */ + ARMul_MCRRs *MCRR[16]; /* MCRR instruction */ + ARMul_CDPs *CDP[16]; /* CDP instruction */ + ARMul_CPReads *CPRead[16]; /* Read CP register */ + ARMul_CPWrites *CPWrite[16]; /* Write CP register */ + unsigned char *CPData[16]; /* Coprocessor data */ unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */ - unsigned EventSet; /* the number of events in the queue */ - unsigned int Now; /* time to the nearest cycle */ - struct EventNode **EventPtr; /* the event list */ + unsigned EventSet; /* the number of events in the queue */ + unsigned int Now; /* time to the nearest cycle */ + struct EventNode **EventPtr; /* the event list */ - unsigned Debug; /* show instructions as they are executed */ - unsigned NresetSig; /* reset the processor */ + unsigned Debug; /* show instructions as they are executed */ + unsigned NresetSig; /* reset the processor */ unsigned NfiqSig; unsigned NirqSig; @@ -356,12 +290,12 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) */ unsigned lateabtSig; - ARMword Vector; /* synthesize aborts in cycle modes */ - ARMword Aborted; /* sticky flag for aborts */ - ARMword Reseted; /* sticky flag for Reset */ + ARMword Vector; /* synthesize aborts in cycle modes */ + ARMword Aborted; /* sticky flag for aborts */ + ARMword Reseted; /* sticky flag for Reset */ ARMword Inted, LastInted; /* sticky flags for interrupts */ - ARMword Base; /* extra hand for base writeback */ - ARMword AbortAddr; /* to keep track of Prefetch aborts */ + ARMword Base; /* extra hand for base writeback */ + ARMword AbortAddr; /* to keep track of Prefetch aborts */ const struct Dbg_HostosInterface *hostif; @@ -378,7 +312,7 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) //chy: 2003-08-11, for different arm core type unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */ unsigned is_v5; /* Are we emulating a v5 architecture ? */ - unsigned is_v5e; /* Are we emulating a v5e architecture ? */ + unsigned is_v5e; /* Are we emulating a v5e architecture ? */ unsigned is_v6; /* Are we emulating a v6 architecture ? */ unsigned is_v7; /* Are we emulating a v7 architecture ? */ unsigned is_XScale; /* Are we emulating an XScale architecture ? */ @@ -387,51 +321,43 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) //chy 2005-09-19 unsigned is_pxa27x; /* Are we emulating a Intel PXA27x co-processor ? */ //chy: seems only used in xscale's CP14 - unsigned int LastTime; /* Value of last call to ARMul_Time() */ + unsigned int LastTime; /* Value of last call to ARMul_Time() */ ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit 3 set */ -//added by ksh:for handle different machs io 2004-3-5 + //added by ksh:for handle different machs io 2004-3-5 ARMul_io mach_io; -/*added by ksh,2004-11-26,some energy profiling*/ + /*added by ksh,2004-11-26,some energy profiling*/ ARMul_Energy energy; -//teawater add for next_dis 2004.10.27----------------------- + //teawater add for next_dis 2004.10.27----------------------- int disassemble; -//AJ2D------------------------------------------ -//teawater add for arm2x86 2005.02.15------------------------------------------- + + //teawater add for arm2x86 2005.02.15------------------------------------------- u32 trap; u32 tea_break_addr; u32 tea_break_ok; int tea_pc; -//AJ2D-------------------------------------------------------------------------- -//teawater add for arm2x86 2005.07.03------------------------------------------- - - /* - * 2007-01-24 removed the term-io functions by Anthony Lee, - * moved to "device/uart/skyeye_uart_stdio.c". - */ -//AJ2D-------------------------------------------------------------------------- -//teawater add for arm2x86 2005.07.05------------------------------------------- + //teawater add for arm2x86 2005.07.05------------------------------------------- //arm_arm A2-18 int abort_model; //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model -//AJ2D-------------------------------------------------------------------------- -//teawater change for return if running tb dirty 2005.07.09--------------------- + + //teawater change for return if running tb dirty 2005.07.09--------------------- void *tb_now; -//AJ2D-------------------------------------------------------------------------- -//teawater add for record reg value to ./reg.txt 2005.07.10--------------------- + + //teawater add for record reg value to ./reg.txt 2005.07.10--------------------- FILE *tea_reg_fd; -//AJ2D-------------------------------------------------------------------------- -/*added by ksh in 2005-10-1*/ + + /*added by ksh in 2005-10-1*/ cpu_config_t *cpu; //mem_config_t *mem_bank; -/* added LPC remap function */ + /* added LPC remap function */ int vector_remap_flag; u32 vector_remap_addr; u32 vector_remap_size; @@ -486,17 +412,14 @@ typedef ARMul_State arm_core_t; #define ARM_Debug_Prop 0x10 #define ARM_Isync_Prop ARM_Debug_Prop #define ARM_Lock_Prop 0x20 -//chy 2003-08-11 #define ARM_v4_Prop 0x40 #define ARM_v5_Prop 0x80 -/*jeff.du 2010-08-05 */ #define ARM_v6_Prop 0xc0 #define ARM_v5e_Prop 0x100 #define ARM_XScale_Prop 0x200 #define ARM_ep9312_Prop 0x400 #define ARM_iWMMXt_Prop 0x800 -//chy 2005-09-19 #define ARM_PXA27X_Prop 0x1000 #define ARM_v7_Prop 0x2000 @@ -591,47 +514,44 @@ typedef ARMul_State arm_core_t; #ifdef __cplusplus extern "C" { #endif -extern void ARMul_EmulateInit (void); -extern void ARMul_Reset (ARMul_State * state); +extern void ARMul_EmulateInit(); +extern void ARMul_Reset(ARMul_State* state); #ifdef __cplusplus } #endif -extern ARMul_State *ARMul_NewState (ARMul_State * state); -extern ARMword ARMul_DoProg (ARMul_State * state); -extern ARMword ARMul_DoInstr (ARMul_State * state); +extern ARMul_State *ARMul_NewState(ARMul_State* state); +extern ARMword ARMul_DoProg(ARMul_State* state); +extern ARMword ARMul_DoInstr(ARMul_State* state); /***************************************************************************\ * Definitons of things for event handling * \***************************************************************************/ -extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay, - unsigned (*func) ()); -extern void ARMul_EnvokeEvent (ARMul_State * state); -extern unsigned int ARMul_Time (ARMul_State * state); +extern void ARMul_ScheduleEvent(ARMul_State* state, unsigned int delay, unsigned(*func) ()); +extern void ARMul_EnvokeEvent(ARMul_State* state); +extern unsigned int ARMul_Time(ARMul_State* state); /***************************************************************************\ * Useful support routines * \***************************************************************************/ -extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode, - unsigned reg); -extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, - ARMword value); -extern ARMword ARMul_GetPC (ARMul_State * state); -extern ARMword ARMul_GetNextPC (ARMul_State * state); -extern void ARMul_SetPC (ARMul_State * state, ARMword value); -extern ARMword ARMul_GetR15 (ARMul_State * state); -extern void ARMul_SetR15 (ARMul_State * state, ARMword value); - -extern ARMword ARMul_GetCPSR (ARMul_State * state); -extern void ARMul_SetCPSR (ARMul_State * state, ARMword value); -extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode); -extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value); +extern ARMword ARMul_GetReg (ARMul_State* state, unsigned mode, unsigned reg); +extern void ARMul_SetReg (ARMul_State* state, unsigned mode, unsigned reg, ARMword value); +extern ARMword ARMul_GetPC(ARMul_State* state); +extern ARMword ARMul_GetNextPC(ARMul_State* state); +extern void ARMul_SetPC(ARMul_State* state, ARMword value); +extern ARMword ARMul_GetR15(ARMul_State* state); +extern void ARMul_SetR15(ARMul_State* state, ARMword value); + +extern ARMword ARMul_GetCPSR(ARMul_State* state); +extern void ARMul_SetCPSR(ARMul_State* state, ARMword value); +extern ARMword ARMul_GetSPSR(ARMul_State* state, ARMword mode); +extern void ARMul_SetSPSR(ARMul_State* state, ARMword mode, ARMword value); /***************************************************************************\ * Definitons of things to handle aborts * \***************************************************************************/ -extern void ARMul_Abort (ARMul_State * state, ARMword address); +extern void ARMul_Abort(ARMul_State* state, ARMword address); #ifdef MODET #define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */ #define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ @@ -649,54 +569,40 @@ extern void ARMul_Abort (ARMul_State * state, ARMword address); * Definitons of things in the memory interface * \***************************************************************************/ -extern unsigned ARMul_MemoryInit (ARMul_State * state, - unsigned int initmemsize); -extern void ARMul_MemoryExit (ARMul_State * state); +extern unsigned ARMul_MemoryInit(ARMul_State* state, unsigned int initmemsize); +extern void ARMul_MemoryExit(ARMul_State* state); -extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, - ARMword isize); -extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, - ARMword isize); +extern ARMword ARMul_LoadInstrS(ARMul_State* state, ARMword address, ARMword isize); +extern ARMword ARMul_LoadInstrN(ARMul_State* state, ARMword address, ARMword isize); #ifdef __cplusplus extern "C" { #endif -extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address, - ARMword isize); +extern ARMword ARMul_ReLoadInstr(ARMul_State* state, ARMword address, ARMword isize); #ifdef __cplusplus } #endif -extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address); -extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address); -extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address); -extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address); - -extern void ARMul_StoreWordS (ARMul_State * state, ARMword address, - ARMword data); -extern void ARMul_StoreWordN (ARMul_State * state, ARMword address, - ARMword data); -extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address, - ARMword data); -extern void ARMul_StoreByte (ARMul_State * state, ARMword address, - ARMword data); - -extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, - ARMword data); -extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, - ARMword data); - -extern void ARMul_Icycles (ARMul_State * state, unsigned number, - ARMword address); -extern void ARMul_Ccycles (ARMul_State * state, unsigned number, - ARMword address); - -extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address); -extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address); -extern void ARMul_WriteWord (ARMul_State * state, ARMword address, - ARMword data); -extern void ARMul_WriteByte (ARMul_State * state, ARMword address, - ARMword data); - -extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword, +extern ARMword ARMul_LoadWordS(ARMul_State* state, ARMword address); +extern ARMword ARMul_LoadWordN(ARMul_State* state, ARMword address); +extern ARMword ARMul_LoadHalfWord(ARMul_State* state, ARMword address); +extern ARMword ARMul_LoadByte(ARMul_State* state, ARMword address); + +extern void ARMul_StoreWordS(ARMul_State* state, ARMword address, ARMword data); +extern void ARMul_StoreWordN(ARMul_State* state, ARMword address, ARMword data); +extern void ARMul_StoreHalfWord(ARMul_State* state, ARMword address, ARMword data); +extern void ARMul_StoreByte(ARMul_State* state, ARMword address, ARMword data); + +extern ARMword ARMul_SwapWord(ARMul_State* state, ARMword address, ARMword data); +extern ARMword ARMul_SwapByte(ARMul_State* state, ARMword address, ARMword data); + +extern void ARMul_Icycles(ARMul_State* state, unsigned number, ARMword address); +extern void ARMul_Ccycles(ARMul_State* state, unsigned number, ARMword address); + +extern ARMword ARMul_ReadWord(ARMul_State* state, ARMword address); +extern ARMword ARMul_ReadByte(ARMul_State* state, ARMword address); +extern void ARMul_WriteWord(ARMul_State* state, ARMword address, ARMword data); +extern void ARMul_WriteByte(ARMul_State* state, ARMword address, ARMword data); + +extern ARMword ARMul_MemAccess(ARMul_State* state, ARMword, ARMword, ARMword, ARMword, ARMword, ARMword, ARMword, ARMword, ARMword, ARMword); @@ -739,66 +645,40 @@ extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword, #define ARMul_CP15_DBCON_E1 0x000c #define ARMul_CP15_DBCON_E0 0x0003 -extern unsigned ARMul_CoProInit (ARMul_State * state); -extern void ARMul_CoProExit (ARMul_State * state); -extern void ARMul_CoProAttach (ARMul_State * state, unsigned number, - ARMul_CPInits * init, ARMul_CPExits * exit, - ARMul_LDCs * ldc, ARMul_STCs * stc, - ARMul_MRCs * mrc, ARMul_MCRs * mcr, - ARMul_MRRCs * mrrc, ARMul_MCRRs * mcrr, - ARMul_CDPs * cdp, - ARMul_CPReads * read, ARMul_CPWrites * write); -extern void ARMul_CoProDetach (ARMul_State * state, unsigned number); +extern unsigned ARMul_CoProInit(ARMul_State* state); +extern void ARMul_CoProExit(ARMul_State* state); +extern void ARMul_CoProAttach (ARMul_State* state, unsigned number, + ARMul_CPInits* init, ARMul_CPExits* exit, + ARMul_LDCs* ldc, ARMul_STCs* stc, + ARMul_MRCs* mrc, ARMul_MCRs* mcr, + ARMul_MRRCs* mrrc, ARMul_MCRRs* mcrr, + ARMul_CDPs* cdp, + ARMul_CPReads* read, ARMul_CPWrites* write); +extern void ARMul_CoProDetach(ARMul_State* state, unsigned number); /***************************************************************************\ * Definitons of things in the host environment * \***************************************************************************/ -extern unsigned ARMul_OSInit (ARMul_State * state); -extern void ARMul_OSExit (ARMul_State * state); +extern unsigned ARMul_OSInit(ARMul_State* state); +extern void ARMul_OSExit(ARMul_State* state); #ifdef __cplusplus extern "C" { #endif -extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number); +extern unsigned ARMul_OSHandleSWI(ARMul_State* state, ARMword number); #ifdef __cplusplus } #endif -extern ARMword ARMul_OSLastErrorP (ARMul_State * state); +extern ARMword ARMul_OSLastErrorP(ARMul_State* state); -extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr); -extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector, - ARMword pc); +extern ARMword ARMul_Debug(ARMul_State* state, ARMword pc, ARMword instr); +extern unsigned ARMul_OSException(ARMul_State* state, ARMword vector, ARMword pc); extern int rdi_log; -/***************************************************************************\ -* Host-dependent stuff * -\***************************************************************************/ - -#ifdef macintosh -pascal void SpinCursor (short increment); /* copied from CursorCtl.h */ -# define HOURGLASS SpinCursor( 1 ) -# define HOURGLASS_RATE 1023 /* 2^n - 1 */ -#endif - -//teawater add for arm2x86 2005.02.14------------------------------------------- -/*ywc 2005-03-31*/ -/* -#include "arm2x86.h" -#include "arm2x86_dp.h" -#include "arm2x86_movl.h" -#include "arm2x86_psr.h" -#include "arm2x86_shift.h" -#include "arm2x86_mem.h" -#include "arm2x86_mul.h" -#include "arm2x86_test.h" -#include "arm2x86_other.h" -#include "list.h" -#include "tb.h" -*/ enum ConditionCode { EQ = 0, NE = 1, @@ -851,32 +731,16 @@ enum ConditionCode { #define ZBIT_SHIFT 30 #define CBIT_SHIFT 29 #define VBIT_SHIFT 28 -#ifdef DBCT -//teawater change for local tb branch directly jump 2005.10.18------------------ -#include "dbct/list.h" -#include "dbct/arm2x86.h" -#include "dbct/arm2x86_dp.h" -#include "dbct/arm2x86_movl.h" -#include "dbct/arm2x86_psr.h" -#include "dbct/arm2x86_shift.h" -#include "dbct/arm2x86_mem.h" -#include "dbct/arm2x86_mul.h" -#include "dbct/arm2x86_test.h" -#include "dbct/arm2x86_other.h" -#include "dbct/arm2x86_coproc.h" -#include "dbct/tb.h" -#endif -//AJ2D-------------------------------------------------------------------------- -//AJ2D-------------------------------------------------------------------------- + #define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\ state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \ state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \ state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \ state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \ - state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\ + state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\ state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\ - state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\ - state->temp,state->loaded,state->decoded);} + state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\ + state->temp,state->loaded,state->decoded);} #define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\ RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ @@ -914,17 +778,30 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\ #define SA1110 0x6901b110 #define SA1100 0x4401a100 -#define PXA250 0x69052100 -#define PXA270 0x69054110 -//#define PXA250 0x69052903 +#define PXA250 0x69052100 +#define PXA270 0x69054110 +//#define PXA250 0x69052903 // 0x69052903; //PXA250 B1 from intel 278522-001.pdf -extern void ARMul_UndefInstr (ARMul_State *, ARMword); -extern void ARMul_FixCPSR (ARMul_State *, ARMword, ARMword); -extern void ARMul_FixSPSR (ARMul_State *, ARMword, ARMword); -extern void ARMul_ConsolePrint (ARMul_State *, const char *, ...); -extern void ARMul_SelectProcessor (ARMul_State *, unsigned); +extern void ARMul_UndefInstr(ARMul_State*, ARMword); +extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword); +extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword); +extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...); +extern void ARMul_SelectProcessor(ARMul_State*, unsigned); + +extern u8 ARMul_SignedSaturatedAdd8(u8, u8); +extern u8 ARMul_SignedSaturatedSub8(u8, u8); +extern u16 ARMul_SignedSaturatedAdd16(u16, u16); +extern u16 ARMul_SignedSaturatedSub16(u16, u16); + +extern u8 ARMul_UnsignedSaturatedAdd8(u8, u8); +extern u16 ARMul_UnsignedSaturatedAdd16(u16, u16); +extern u8 ARMul_UnsignedSaturatedSub8(u8, u8); +extern u16 ARMul_UnsignedSaturatedSub16(u16, u16); +extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8); +extern u32 ARMul_SignedSatQ(s32, u8, bool*); +extern u32 ARMul_UnsignedSatQ(s32, u8, bool*); #define DIFF_LOG 0 #define SAVE_LOG 0 diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h index 075fc7e9e..3ea14b5a3 100644 --- a/src/core/arm/skyeye_common/armemu.h +++ b/src/core/arm/skyeye_common/armemu.h @@ -23,8 +23,6 @@ //extern ARMword isize; -#define DEBUG(...) DEBUG_LOG(ARM11, __VA_ARGS__) - /* Shift Opcodes. */ #define LSL 0 #define LSR 1 @@ -36,7 +34,7 @@ #define ZBIT (1L << 30) #define CBIT (1L << 29) #define VBIT (1L << 28) -#define SBIT (1L << 27) +#define QBIT (1L << 27) #define IBIT (1L << 7) #define FBIT (1L << 6) #define IFBITS (3L << 6) @@ -158,13 +156,14 @@ #define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) #define R15MODE (state->Reg[15] & R15MODEBITS) -#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27)) +#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (QFLAG << 27)) #define EINT (IFFLAGS << 6) #define ER15INT (IFFLAGS << 26) #define EMODE (state->Mode) +#define EGEBITS (state->GEFlag & 0x000F0000) #ifdef MODET -#define CPSR (ECC | EINT | EMODE | (TFLAG << 5)) +#define CPSR (ECC | EGEBITS | (EFLAG << 9) | (AFLAG << 8) | EINT | (TFLAG << 5) | EMODE) #else #define CPSR (ECC | EINT | EMODE) #endif @@ -485,7 +484,7 @@ tdstate; * out-of-updated with the newer ISA. * -- Michael.Kang ********************************************************************************/ -#define UNDEF_WARNING WARN_LOG(ARM11, "undefined or unpredicted behavior for arm instruction.\n"); +#define UNDEF_WARNING LOG_WARNING(Core_ARM11, "undefined or unpredicted behavior for arm instruction."); /* Macros to scrutinize instructions. */ #define UNDEF_Test UNDEF_WARNING @@ -603,6 +602,7 @@ 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/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index 454f60099..5c036caeb 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp @@ -32,8 +32,7 @@ //ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ -unsigned -VFPInit (ARMul_State *state) +unsigned VFPInit(ARMul_State* state) { state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION; @@ -46,8 +45,7 @@ VFPInit (ARMul_State *state) return 0; } -unsigned -VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value) +unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value) { /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -61,10 +59,21 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value) /* CRn/opc1 CRm/opc2 */ - if (CoProc == 10 || CoProc == 11) { -#define VFP_MRC_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MRC_TRANS + if (CoProc == 10 || CoProc == 11) + { + if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0) + { + /* VMOV r to s */ + /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ + VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value); + return ARMul_DONE; + } + + if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0) + { + VMRS(state, CRn, Rt, value); + return ARMul_DONE; + } } DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); @@ -72,8 +81,7 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value) return ARMul_CANT; } -unsigned -VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value) +unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value) { /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -86,10 +94,33 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value) /* TODO check access permission */ /* CRn/opc1 CRm/opc2 */ - if (CoProc == 10 || CoProc == 11) { -#define VFP_MCR_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MCR_TRANS + if (CoProc == 10 || CoProc == 11) + { + if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0) + { + /* VMOV s to r */ + /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ + VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value); + return ARMul_DONE; + } + + if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0) + { + VMSR(state, CRn, Rt); + return ARMul_DONE; + } + + if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0) + { + VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); + return ARMul_DONE; + } + + if (CoProc == 11 && CRm == 0) + { + VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); + return ARMul_DONE; + } } DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); @@ -97,8 +128,7 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value) return ARMul_CANT; } -unsigned -VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * value2) +unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2) { /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -107,10 +137,20 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu int Rt2 = BITS (16, 19); int CRm = BITS (0, 3); - if (CoProc == 10 || CoProc == 11) { -#define VFP_MRRC_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MRRC_TRANS + if (CoProc == 10 || CoProc == 11) + { + if (CoProc == 10 && (OPC_1 & 0xD) == 1) + { + VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); + return ARMul_DONE; + } + + if (CoProc == 11 && (OPC_1 & 0xD) == 1) + { + /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ + VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2); + return ARMul_DONE; + } } DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", instr, CoProc, OPC_1, Rt, Rt2, CRm); @@ -118,8 +158,7 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu return ARMul_CANT; } -unsigned -VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2) +unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2) { /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -132,10 +171,20 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2) /* CRn/opc1 CRm/opc2 */ - if (CoProc == 11 || CoProc == 10) { -#define VFP_MCRR_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MCRR_TRANS + if (CoProc == 11 || CoProc == 10) + { + if (CoProc == 10 && (OPC_1 & 0xD) == 1) + { + VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); + return ARMul_DONE; + } + + if (CoProc == 11 && (OPC_1 & 0xD) == 1) + { + /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ + VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2); + return ARMul_DONE; + } } DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", instr, CoProc, OPC_1, Rt, Rt2, CRm); @@ -143,8 +192,7 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2) return ARMul_CANT; } -unsigned -VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value) +unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value) { /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -175,9 +223,17 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value) } #endif -#define VFP_STC_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_STC_TRANS + if (P == 1 && W == 0) + { + return VSTR(state, type, instr, value); + } + + if (P == 1 && U == 0 && W == 1 && Rn == 0xD) + { + return VPUSH(state, type, instr, value); + } + + return VSTM(state, type, instr, value); } DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", instr, CoProc, CRd, Rn, imm8, P, U, D, W); @@ -185,8 +241,7 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value) return ARMul_CANT; } -unsigned -VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value) +unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value) { /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -204,10 +259,19 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value) DEBUG("In %s, UNDEFINED\n", __FUNCTION__); exit(-1); } - if (CoProc == 10 || CoProc == 11) { -#define VFP_LDC_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_LDC_TRANS + if (CoProc == 10 || CoProc == 11) + { + if (P == 1 && W == 0) + { + return VLDR(state, type, instr, value); + } + + if (P == 0 && U == 1 && W == 1 && Rn == 0xD) + { + return VPOP(state, type, instr, value); + } + + return VLDM(state, type, instr, value); } DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", instr, CoProc, CRd, Rn, imm8, P, U, D, W); @@ -215,8 +279,7 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value) return ARMul_CANT; } -unsigned -VFPCDP (ARMul_State * state, unsigned type, u32 instr) +unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr) { /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ int CoProc = BITS (8, 11); /* 10 or 11 */ @@ -275,10 +338,83 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr) /* CRn/opc1 CRm/opc2 */ - if (CoProc == 10 || CoProc == 11) { -#define VFP_CDP_TRANS -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_CDP_TRANS + if (CoProc == 10 || CoProc == 11) + { + if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0) + DBG("VMLA :\n"); + + if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2) + DBG("VMLS :\n"); + + if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2) + DBG("VNMLA :\n"); + + if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0) + DBG("VNMLS :\n"); + + if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2) + DBG("VNMUL :\n"); + + if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0) + DBG("VMUL :\n"); + + if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0) + DBG("VADD :\n"); + + if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2) + DBG("VSUB :\n"); + + if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0) + DBG("VDIV :\n"); + + if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0) + { + unsigned int single = BIT(8) == 0; + unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); + unsigned int imm; + instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */ + + if (single) + imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19; + else + imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16; + + VMOVI(state, single, d, imm); + return ARMul_DONE; + } + + if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2) + { + unsigned int single = BIT(8) == 0; + unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); + unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);; + VMOVR(state, single, d, m); + return ARMul_DONE; + } + + if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6) + DBG("VABS :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2) + DBG("VNEG :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6) + DBG("VSQRT :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2) + DBG("VCMP(1) :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0) + DBG("VCMP(2) :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6) + DBG("VCVT(BDS) :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2) + DBG("VCVT(BFF) :\n"); + + if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2) + DBG("VCVT(BFI) :\n"); int exceptions = 0; if (CoProc == 10) @@ -296,23 +432,93 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr) /* ----------- MRC ------------ */ -#define VFP_MRC_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MRC_IMPL - -#define VFP_MRRC_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MRRC_IMPL - +void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value) +{ + DBG("VMOV(BRS) :\n"); + if (to_arm) + { + DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]); + *value = state->ExtReg[n]; + } + else + { + DBG("\ts%d <= r%d=[%x]\n", n, t, *value); + state->ExtReg[n] = *value; + } +} +void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value) +{ + DBG("VMRS :"); + if (reg == 1) + { + if (Rt != 15) + { + *value = state->VFP[VFP_OFFSET(VFP_FPSCR)]; + DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]); + } + else + { + *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ; + DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); + } + } + else + { + switch (reg) + { + case 0: + *value = state->VFP[VFP_OFFSET(VFP_FPSID)]; + DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]); + 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: + *value = state->VFP[VFP_OFFSET(VFP_FPEXC)]; + DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]); + break; + default: + DBG("\tSUBARCHITECTURE DEFINED\n"); + break; + } + } +} +void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) +{ + DBG("VMOV(BRRD) :\n"); + if (to_arm) + { + DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]); + *value2 = state->ExtReg[n*2+1]; + *value1 = state->ExtReg[n*2]; + } + else + { + DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1); + state->ExtReg[n*2+1] = *value2; + state->ExtReg[n*2] = *value1; + } +} /* ----------- MCR ------------ */ -#define VFP_MCR_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MCR_IMPL - -#define VFP_MCRR_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_MCRR_IMPL +void VMSR(ARMul_State* state, ARMword reg, ARMword Rt) +{ + if (reg == 1) + { + DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]); + state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt]; + } + else if (reg == 8) + { + DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]); + state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt]; + } +} /* Memory operation are not inlined, as old Interpreter and Fast interpreter don't have the same memory operation interface. @@ -322,21 +528,342 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr) of vfp instructions in old interpreter and fast interpreter are separate. */ /* ----------- STC ------------ */ -#define VFP_STC_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_STC_IMPL +int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value) +{ + static int i = 0; + static int single_reg, add, d, n, imm32, regs; + if (type == ARMul_FIRST) + { + single_reg = BIT(8) == 0; /* Double precision */ + add = BIT(23); /* */ + imm32 = BITS(0,7)<<2; /* may not be used */ + d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ + n = BITS(16, 19); /* destination register */ + DBG("VSTR :\n"); + + i = 0; + regs = 1; + + return ARMul_DONE; + } + else if (type == ARMul_DATA) + { + if (single_reg) + { + *value = state->ExtReg[d+i]; + DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]); + i++; + if (i < regs) + return ARMul_INC; + else + return ARMul_DONE; + } + else + { + /* FIXME Careful of endianness, may need to rework this */ + *value = state->ExtReg[d*2+i]; + DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]); + i++; + if (i < regs*2) + return ARMul_INC; + else + return ARMul_DONE; + } + } + + return -1; +} +int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value) +{ + static int i = 0; + static int single_regs, add, wback, d, n, imm32, regs; + if (type == ARMul_FIRST) + { + single_regs = BIT(8) == 0; /* Single precision */ + d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ + imm32 = BITS(0,7)<<2; /* may not be used */ + regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */ + + DBG("VPUSH :\n"); + DBG("\tsp[%x]", state->Reg[R13]); + state->Reg[R13] = state->Reg[R13] - imm32; + DBG("=>[%x]\n", state->Reg[R13]); + + i = 0; + + return ARMul_DONE; + } + else if (type == ARMul_DATA) + { + if (single_regs) + { + *value = state->ExtReg[d + i]; + DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]); + i++; + if (i < regs) + return ARMul_INC; + else + return ARMul_DONE; + } + else + { + /* FIXME Careful of endianness, may need to rework this */ + *value = state->ExtReg[d*2 + i]; + DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]); + i++; + if (i < regs*2) + return ARMul_INC; + else + return ARMul_DONE; + } + } + + return -1; +} +int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value) +{ + static int i = 0; + static int single_regs, add, wback, d, n, imm32, regs; + if (type == ARMul_FIRST) + { + single_regs = BIT(8) == 0; /* Single precision */ + add = BIT(23); /* */ + wback = BIT(21); /* write-back */ + d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ + n = BITS(16, 19); /* destination register */ + imm32 = BITS(0,7) * 4; /* may not be used */ + regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */ + + DBG("VSTM :\n"); + + if (wback) { + state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); + DBG("\twback r%d[%x]\n", n, state->Reg[n]); + } + + i = 0; + + return ARMul_DONE; + } + else if (type == ARMul_DATA) + { + if (single_regs) + { + *value = state->ExtReg[d + i]; + DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]); + i++; + if (i < regs) + return ARMul_INC; + else + return ARMul_DONE; + } + else + { + /* FIXME Careful of endianness, may need to rework this */ + *value = state->ExtReg[d*2 + i]; + DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]); + i++; + if (i < regs*2) + return ARMul_INC; + else + return ARMul_DONE; + } + } + + return -1; +} /* ----------- LDC ------------ */ -#define VFP_LDC_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_LDC_IMPL +int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value) +{ + static int i = 0; + static int single_regs, add, wback, d, n, imm32, regs; + if (type == ARMul_FIRST) + { + single_regs = BIT(8) == 0; /* Single precision */ + d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ + imm32 = BITS(0,7)<<2; /* may not be used */ + regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */ + DBG("VPOP :\n"); + DBG("\tsp[%x]", state->Reg[R13]); + state->Reg[R13] = state->Reg[R13] + imm32; + DBG("=>[%x]\n", state->Reg[R13]); + + i = 0; + + return ARMul_DONE; + } + else if (type == ARMul_TRANSFER) + { + return ARMul_DONE; + } + else if (type == ARMul_DATA) + { + if (single_regs) + { + state->ExtReg[d + i] = value; + DBG("\ts%d <= [%x]\n", d + i, value); + i++; + if (i < regs) + return ARMul_INC; + else + return ARMul_DONE; + } + else + { + /* FIXME Careful of endianness, may need to rework this */ + state->ExtReg[d*2 + i] = value; + DBG("\ts%d <= [%x]\n", d*2 + i, value); + i++; + if (i < regs*2) + return ARMul_INC; + else + return ARMul_DONE; + } + } + + return -1; +} +int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value) +{ + static int i = 0; + static int single_reg, add, d, n, imm32, regs; + if (type == ARMul_FIRST) + { + single_reg = BIT(8) == 0; /* Double precision */ + add = BIT(23); /* */ + imm32 = BITS(0,7)<<2; /* may not be used */ + d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ + n = BITS(16, 19); /* destination register */ + + DBG("VLDR :\n"); + + i = 0; + regs = 1; + + return ARMul_DONE; + } + else if (type == ARMul_TRANSFER) + { + return ARMul_DONE; + } + else if (type == ARMul_DATA) + { + if (single_reg) + { + state->ExtReg[d+i] = value; + DBG("\ts%d <= [%x]\n", d+i, value); + i++; + if (i < regs) + return ARMul_INC; + else + return ARMul_DONE; + } + else + { + /* FIXME Careful of endianness, may need to rework this */ + state->ExtReg[d*2+i] = value; + DBG("\ts[%d] <= [%x]\n", d*2+i, value); + i++; + if (i < regs*2) + return ARMul_INC; + else + return ARMul_DONE; + } + } + + return -1; +} +int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value) +{ + static int i = 0; + static int single_regs, add, wback, d, n, imm32, regs; + if (type == ARMul_FIRST) + { + single_regs = BIT(8) == 0; /* Single precision */ + add = BIT(23); /* */ + wback = BIT(21); /* write-back */ + d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ + n = BITS(16, 19); /* destination register */ + imm32 = BITS(0,7) * 4; /* may not be used */ + regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */ + + DBG("VLDM :\n"); + + if (wback) { + state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); + DBG("\twback r%d[%x]\n", n, state->Reg[n]); + } + + i = 0; + + return ARMul_DONE; + } + else if (type == ARMul_DATA) + { + if (single_regs) + { + state->ExtReg[d + i] = value; + DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]); + i++; + if (i < regs) + return ARMul_INC; + else + return ARMul_DONE; + } + else + { + /* FIXME Careful of endianness, may need to rework this */ + state->ExtReg[d*2 + i] = value; + DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]); + i++; + if (i < regs*2) + return ARMul_INC; + else + return ARMul_DONE; + } + } + + return -1; +} /* ----------- CDP ------------ */ -#define VFP_CDP_IMPL -#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" -#undef VFP_CDP_IMPL +void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) +{ + DBG("VMOV(I) :\n"); + + if (single) + { + DBG("\ts%d <= [%x]\n", d, imm); + state->ExtReg[d] = imm; + } + else + { + /* Check endian please */ + DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0); + state->ExtReg[d*2+1] = imm; + state->ExtReg[d*2] = 0; + } +} +void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m) +{ + DBG("VMOV(R) :\n"); + + if (single) + { + DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]); + state->ExtReg[d] = state->ExtReg[m]; + } + else + { + /* Check endian please */ + DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]); + state->ExtReg[d*2+1] = state->ExtReg[m*2+1]; + state->ExtReg[d*2] = state->ExtReg[m*2]; + } +} /* Miscellaneous functions */ int32_t vfp_get_float(arm_core_t* state, unsigned int reg) @@ -366,8 +893,6 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg) state->ExtReg[reg*2+1] = (uint32_t) (val>>32); } - - /* * Process bitmask of exception conditions. (from vfpmodule.c) */ diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h index 7256701f3..f9e8d521d 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.h +++ b/src/core/arm/skyeye_common/vfp/vfp.h @@ -27,6 +27,12 @@ #include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */ +#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst); +#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1); +#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__); +#define CHECK_VFP_ENABLED +#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);} + unsigned VFPInit (ARMul_State *state); unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value); unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value); diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 45208fb13..27dc8a008 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp @@ -28,34 +28,19 @@ /* ----------------------------------------------------------------------- */ /* VMLA */ /* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */ -#define vfpinstr vmla -#define vfpinstr_inst vmla_inst -#define VFPLABEL_INST VMLA_INST -#ifdef VFP_DECODE -{"vmla", 4, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmla", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmla_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vmla_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -69,15 +54,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMLA_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VMLA :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmla_inst *inst_cream = (vmla_inst *)inst_base->component; int ret; @@ -89,22 +73,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmla_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0) -{ - DBG("VMLA :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmla), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -114,7 +93,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -168,41 +147,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VNMLS */ /* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */ -#define vfpinstr vmls -#define vfpinstr_inst vmls_inst -#define VFPLABEL_INST VMLS_INST -#ifdef VFP_DECODE -{"vmls", 7, ARMVFP2, 28 , 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmls", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmls_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vmls_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -216,15 +177,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMLS_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VMLS :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmls_inst *inst_cream = (vmls_inst *)inst_base->component; int ret; @@ -236,22 +196,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmls_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2) -{ - DBG("VMLS :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmls), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -261,7 +216,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -315,47 +270,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VNMLA */ /* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */ -#define vfpinstr vnmla -#define vfpinstr_inst vnmla_inst -#define VFPLABEL_INST VNMLA_INST -#ifdef VFP_DECODE -//{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -{"vnmla", 4, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0}, -{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -//{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vnmla", 0, ARMVFP2, 0}, -{"vnmla", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vnmla_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vnmla_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -369,15 +300,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VNMLA_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VNMLA :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; int ret; @@ -389,23 +319,18 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vnmla_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2) -{ - DBG("VNMLA :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vnmla), +DYNCOM_FILL_ACTION(vnmla), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -415,7 +340,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -469,41 +394,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VNMLS */ /* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */ -#define vfpinstr vnmls -#define vfpinstr_inst vnmls_inst -#define VFPLABEL_INST VNMLS_INST -#ifdef VFP_DECODE -{"vnmls", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vnmls", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif + #ifdef VFP_INTERPRETER_STRUCT typedef struct _vnmls_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vnmls_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst)); + vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); inst_base->idx = index; @@ -517,15 +425,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VNMLS_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VNMLS :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; int ret; @@ -537,22 +444,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vnmls_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0) -{ - DBG("VNMLS :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vnmls), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -562,7 +464,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -616,41 +518,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VNMUL */ /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ -#define vfpinstr vnmul -#define vfpinstr_inst vnmul_inst -#define VFPLABEL_INST VNMUL_INST -#ifdef VFP_DECODE -{"vnmul", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vnmul", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vnmul_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vnmul_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst)); + vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); inst_base->idx = index; @@ -664,15 +548,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VNMUL_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VNMUL :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; int ret; @@ -684,22 +567,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vnmul_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2) -{ - DBG("VNMUL :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vnmul), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -709,7 +587,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -753,41 +631,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST + /* ----------------------------------------------------------------------- */ /* VMUL */ /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ -#define vfpinstr vmul -#define vfpinstr_inst vmul_inst -#define VFPLABEL_INST VMUL_INST -#ifdef VFP_DECODE -{"vmul", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmul", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmul_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vmul_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst)); + vmul_inst *inst_cream = (vmul_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); inst_base->idx = index; @@ -801,15 +662,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMUL_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VMUL :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmul_inst *inst_cream = (vmul_inst *)inst_base->component; int ret; @@ -821,22 +681,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmul_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0) -{ - DBG("VMUL :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmul), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -846,7 +701,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -904,41 +759,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VADD */ /* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */ -#define vfpinstr vadd -#define vfpinstr_inst vadd_inst -#define VFPLABEL_INST VADD_INST -#ifdef VFP_DECODE -{"vadd", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vadd", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vadd_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vadd_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst)); + vadd_inst *inst_cream = (vadd_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); inst_base->idx = index; @@ -952,15 +789,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VADD_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VADD :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vadd_inst *inst_cream = (vadd_inst *)inst_base->component; int ret; @@ -972,22 +808,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vadd_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0) -{ - DBG("VADD :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vadd), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -997,7 +828,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -1049,41 +880,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VSUB */ /* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */ -#define vfpinstr vsub -#define vfpinstr_inst vsub_inst -#define VFPLABEL_INST VSUB_INST -#ifdef VFP_DECODE -{"vsub", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vsub", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vsub_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vsub_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -1097,15 +910,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VSUB_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VSUB :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vsub_inst *inst_cream = (vsub_inst *)inst_base->component; int ret; @@ -1117,22 +929,16 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vsub_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2) -{ - DBG("VSUB :\n"); -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vsub), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -1141,7 +947,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -1193,41 +999,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VDIV */ /* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */ -#define vfpinstr vdiv -#define vfpinstr_inst vdiv_inst -#define VFPLABEL_INST VDIV_INST -#ifdef VFP_DECODE -{"vdiv", 5, ARMVFP2, 23, 27, 0x1d, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vdiv", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vdiv_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vdiv_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -1241,15 +1029,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VDIV_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VDIV :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; int ret; @@ -1261,22 +1048,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vdiv_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0) -{ - DBG("VDIV :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vdiv), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -1286,7 +1068,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -1338,43 +1120,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMOVI move immediate */ /* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */ /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ -#define vfpinstr vmovi -#define vfpinstr_inst vmovi_inst -#define VFPLABEL_INST VMOVI_INST -#ifdef VFP_DECODE -{"vmov(i)", 4, ARMVFP3, 23, 27, 0x1d, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmov(i)", 0, ARMVFP3, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovi_inst { unsigned int single; unsigned int d; unsigned int imm; -} vfpinstr_inst; +} vmovi_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -1392,62 +1156,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVI_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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(vfpinstr_inst)); + INC_PC(sizeof(vmovi_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ( (OPC_1 & 0xb) == 0xb && BITS(4, 7) == 0) -{ - unsigned int single = BIT(8) == 0; - unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); - unsigned int imm; - instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */ - if (single) { - imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19; - } else { - imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16; - } - VMOVI(state, single, d, imm); - return ARMul_DONE; -} -#endif -#ifdef VFP_CDP_IMPL -void VMOVI(ARMul_State * state, ARMword single, ARMword d, ARMword imm) -{ - DBG("VMOV(I) :\n"); - - if (single) - { - DBG("\ts%d <= [%x]\n", d, imm); - state->ExtReg[d] = imm; - } - else - { - /* Check endian please */ - DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0); - state->ExtReg[d*2+1] = imm; - state->ExtReg[d*2] = 0; - } -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovi), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -1456,7 +1185,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -1482,44 +1211,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMOVR move register */ /* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */ /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */ -#define vfpinstr vmovr -#define vfpinstr_inst vmovr_inst -#define VFPLABEL_INST VMOVR_INST -#ifdef VFP_DECODE -{"vmov(r)", 5, ARMVFP3, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmov(r)", 0, ARMVFP3, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovr_inst { unsigned int single; unsigned int d; unsigned int m; -} vfpinstr_inst; +} vmovr_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -1533,56 +1244,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVR_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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(vfpinstr_inst)); + INC_PC(sizeof(vmovr_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ( (OPC_1 & 0xb) == 0xb && CRn == 0 && (OPC_2 & 0x6) == 0x2 ) -{ - unsigned int single = BIT(8) == 0; - unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); - unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);; - VMOVR(state, single, d, m); - return ARMul_DONE; -} -#endif -#ifdef VFP_CDP_IMPL -void VMOVR(ARMul_State * state, ARMword single, ARMword d, ARMword m) -{ - DBG("VMOV(R) :\n"); - - if (single) - { - DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]); - state->ExtReg[d] = state->ExtReg[m]; - } - else - { - /* Check endian please */ - DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]); - state->ExtReg[d*2+1] = state->ExtReg[m*2+1]; - state->ExtReg[d*2] = state->ExtReg[m*2]; - } -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovr), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -1594,7 +1276,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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)); @@ -1613,41 +1295,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VABS */ /* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */ -#define vfpinstr vabs -#define vfpinstr_inst vabs_inst -#define VFPLABEL_INST VABS_INST -#ifdef VFP_DECODE -{"vabs", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vabs", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vabs_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vabs_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_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; @@ -1661,15 +1325,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VABS_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VABS :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vabs_inst *inst_cream = (vabs_inst *)inst_base->component; int ret; @@ -1681,22 +1344,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vabs_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6) -{ - DBG("VABS :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vabs), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -1706,7 +1364,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -1744,42 +1402,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VNEG */ /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ -#define vfpinstr vneg -#define vfpinstr_inst vneg_inst -#define VFPLABEL_INST VNEG_INST -#ifdef VFP_DECODE -//{"vneg", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0}, -{"vneg", 5, ARMVFP2, 23, 27, 0x1d, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vneg", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif + #ifdef VFP_INTERPRETER_STRUCT typedef struct _vneg_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vneg_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_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; @@ -1793,15 +1433,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VNEG_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VNEG :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vneg_inst *inst_cream = (vneg_inst *)inst_base->component; int ret; @@ -1813,22 +1452,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vneg_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2) -{ - DBG("VNEG :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vneg), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -1838,7 +1472,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -1876,41 +1510,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VSQRT */ /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */ -#define vfpinstr vsqrt -#define vfpinstr_inst vsqrt_inst -#define VFPLABEL_INST VSQRT_INST -#ifdef VFP_DECODE -{"vsqrt", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vsqrt", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vsqrt_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vsqrt_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -1924,15 +1540,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VSQRT_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VSQRT :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; int ret; @@ -1944,22 +1559,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vsqrt_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6) -{ - DBG("VSQRT :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vsqrt), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -1969,7 +1579,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -1995,41 +1605,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VCMP VCMPE */ /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */ -#define vfpinstr vcmp -#define vfpinstr_inst vcmp_inst -#define VFPLABEL_INST VCMP_INST -#ifdef VFP_DECODE -{"vcmp", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vcmp", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcmp_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vcmp_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2043,15 +1635,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VCMP_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VCMP(1) :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; int ret; @@ -2063,22 +1654,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vcmp_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2) -{ - DBG("VCMP(1) :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vcmp), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -2087,7 +1673,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -2141,41 +1727,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VCMP VCMPE */ /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */ -#define vfpinstr vcmp2 -#define vfpinstr_inst vcmp2_inst -#define VFPLABEL_INST VCMP2_INST -#ifdef VFP_DECODE -{"vcmp2", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vcmp2", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcmp2_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vcmp2_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2189,15 +1757,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VCMP2_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VCMP(2) :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; int ret; @@ -2209,22 +1776,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vcmp2_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0) -{ - DBG("VCMP(2) :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vcmp2), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -2233,7 +1795,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -2287,41 +1849,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VCVTBDS between double and single */ /* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */ -#define vfpinstr vcvtbds -#define vfpinstr_inst vcvtbds_inst -#define VFPLABEL_INST VCVTBDS_INST -#ifdef VFP_DECODE -{"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vcvt(bds)", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcvtbds_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vcvtbds_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2335,15 +1879,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VCVTBDS_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VCVT(BDS) :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; int ret; @@ -2355,22 +1898,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vcvtbds_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6) -{ - DBG("VCVT(BDS) :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vcvtbds), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -2379,7 +1917,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -2407,41 +1945,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VCVTBFF between floating point and fixed point */ /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ -#define vfpinstr vcvtbff -#define vfpinstr_inst vcvtbff_inst -#define VFPLABEL_INST VCVTBFF_INST -#ifdef VFP_DECODE -{"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1d, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 0x5, 6, 6, 1}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vcvt(bff)", 0, ARMVFP3, 4, 4, 1}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcvtbff_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vcvtbff_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2455,15 +1975,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VCVTBFF_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VCVT(BFF) :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; int ret; @@ -2475,22 +1994,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vcvtbff_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2) -{ - DBG("VCVT(BFF) :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vcvtbff), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -2499,47 +2013,29 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VCVTBFI between floating point and integer */ /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */ -#define vfpinstr vcvtbfi -#define vfpinstr_inst vcvtbfi_inst -#define VFPLABEL_INST VCVTBFI_INST -#ifdef VFP_DECODE -{"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1d, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vcvt(bfi)", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vcvtbfi_inst { unsigned int instr; unsigned int dp_operation; -} vfpinstr_inst; +} vcvtbfi_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2554,15 +2050,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VCVTBFI_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; DBG("VCVT(BFI) :\n"); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; int ret; @@ -2574,22 +2069,17 @@ VFPLABEL_INST: CHECK_VFP_CDP_RET; } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vcvtbfi_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_CDP_TRANS -if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2) -{ - DBG("VCVT(BFI) :\n"); -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vcvtbfi), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -2600,7 +2090,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -2694,9 +2184,6 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){ return 0; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* MRC / MCR instructions */ @@ -2707,35 +2194,20 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){ /* VMOVBRS between register and single precision */ /* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */ /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ -#define vfpinstr vmovbrs -#define vfpinstr_inst vmovbrs_inst -#define VFPLABEL_INST VMOVBRS_INST -#ifdef VFP_DECODE -{"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmovbrs", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrs_inst { unsigned int to_arm; unsigned int t; unsigned int n; -} vfpinstr_inst; +} vmovbrs_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2750,61 +2222,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVBRS_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - - vfpinstr_inst *inst_cream = (vfpinstr_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(vfpinstr_inst)); + INC_PC(sizeof(vmovbrs_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MRC_TRANS -if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0) -{ - /* VMOV r to s */ - /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ - VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value); - return ARMul_DONE; -} -#endif -#ifdef VFP_MCR_TRANS -if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0) -{ - /* VMOV s to r */ - /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ - VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value); - return ARMul_DONE; -} -#endif -#ifdef VFP_MRC_IMPL -void VMOVBRS(ARMul_State * state, ARMword to_arm, ARMword t, ARMword n, ARMword *value) -{ - DBG("VMOV(BRS) :\n"); - if (to_arm) - { - DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]); - *value = state->ExtReg[n]; - } - else - { - DBG("\ts%d <= r%d=[%x]\n", n, t, *value); - state->ExtReg[n] = *value; - } -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovbrs), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -2813,7 +2251,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -2832,42 +2270,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMSR */ /* cond 1110 1110 reg- Rt-- 1010 0001 0000 */ /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ -#define vfpinstr vmsr -#define vfpinstr_inst vmsr_inst -#define VFPLABEL_INST VMSR_INST -#ifdef VFP_DECODE -{"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmsr", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmsr_inst { unsigned int reg; unsigned int Rd; -} vfpinstr_inst; +} vmsr_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -2881,52 +2301,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMSR_INST: { - INC_ICOUNTER; 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; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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(vfpinstr_inst)); + INC_PC(sizeof(vmsr_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MCR_TRANS -if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0) -{ - VMSR(state, CRn, Rt); - return ARMul_DONE; -} -#endif -#ifdef VFP_MCR_IMPL -void VMSR(ARMul_State * state, ARMword reg, ARMword Rt) -{ - if (reg == 1) - { - DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]); - state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt]; - } - else if (reg == 8) - { - DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]); - state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt]; - } -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmsr), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -2936,7 +2334,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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 :"); @@ -2969,44 +2367,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMOVBRC register to scalar */ /* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */ /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */ -#define vfpinstr vmovbrc -#define vfpinstr_inst vmovbrc_inst -#define VFPLABEL_INST VMOVBRC_INST -#ifdef VFP_DECODE -{"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8,11,0xB, 0,4,0x10}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmovbrc", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrc_inst { unsigned int esize; unsigned int index; unsigned int d; unsigned int t; -} vfpinstr_inst; +} vmovbrc_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -3023,34 +2403,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVBRC_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmovbrc_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MCR_TRANS -if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0) -{ - VFP_DEBUG_UNIMPLEMENTED(VMOVBRC); - return ARMul_DONE; -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovbrc), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -3059,48 +2432,30 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMRS */ /* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */ /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */ -#define vfpinstr vmrs -#define vfpinstr_inst vmrs_inst -#define VFPLABEL_INST VMRS_INST -#ifdef VFP_DECODE -{"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xa10}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmrs", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmrs_inst { unsigned int reg; unsigned int Rt; -} vfpinstr_inst; +} vmrs_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -3109,21 +2464,20 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) inst_cream->reg = BITS(inst, 16, 19); inst_cream->Rt = BITS(inst, 12, 15); - + return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMRS_INST: { - INC_ICOUNTER; 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; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; DBG("VMRS :"); @@ -3170,67 +2524,17 @@ VFPLABEL_INST: } } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmrs_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MRC_TRANS -if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0) -{ - VMRS(state, CRn, Rt, value); - return ARMul_DONE; -} -#endif -#ifdef VFP_MRC_IMPL -void VMRS(ARMul_State * state, ARMword reg, ARMword Rt, ARMword * value) -{ - DBG("VMRS :"); - if (reg == 1) - { - if (Rt != 15) - { - *value = state->VFP[VFP_OFFSET(VFP_FPSCR)]; - DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]); - } - else - { - *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ; - DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); - } - } - else - { - switch (reg) - { - case 0: - *value = state->VFP[VFP_OFFSET(VFP_FPSID)]; - DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]); - 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: - *value = state->VFP[VFP_OFFSET(VFP_FPEXC)]; - DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]); - break; - default: - DBG("\tSUBARCHITECTURE DEFINED\n"); - break; - } - } -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmrs), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -3241,7 +2545,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -3292,44 +2596,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMOVBCR scalar to register */ /* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */ /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */ -#define vfpinstr vmovbcr -#define vfpinstr_inst vmovbcr_inst -#define VFPLABEL_INST VMOVBCR_INST -#ifdef VFP_DECODE -{"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11,0xB, 0,4, 0x10}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmovbcr", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbcr_inst { unsigned int esize; unsigned int index; unsigned int d; unsigned int t; -} vfpinstr_inst; +} vmovbcr_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -3346,34 +2632,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVBCR_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmovbcr_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MCR_TRANS -if (CoProc == 11 && CRm == 0) -{ - VFP_DEBUG_UNIMPLEMENTED(VMOVBCR); - return ARMul_DONE; -} -#endif + #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovbcr), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -3382,15 +2661,12 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* MRRC / MCRR instructions */ @@ -3401,36 +2677,21 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc /* VMOVBRRSS between 2 registers to 2 singles */ /* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */ /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ -#define vfpinstr vmovbrrss -#define vfpinstr_inst vmovbrrss_inst -#define VFPLABEL_INST VMOVBRRSS_INST -#ifdef VFP_DECODE -{"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmovbrrss", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrrss_inst { unsigned int to_arm; unsigned int t; unsigned int t2; unsigned int m; -} vfpinstr_inst; +} vmovbrrss_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -3446,41 +2707,26 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVBRRSS_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component; VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vmovbrrss_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MCRR_TRANS -if (CoProc == 10 && (OPC_1 & 0xD) == 1) -{ - VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); - return ARMul_DONE; -} -#endif -#ifdef VFP_MRRC_TRANS -if (CoProc == 10 && (OPC_1 & 0xD) == 1) -{ - VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS); - return ARMul_DONE; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovbrrss), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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; DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); @@ -3489,50 +2735,32 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +int DYNCOM_TRANS(vmovbrrss)(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; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VMOVBRRD between 2 registers and 1 double */ /* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */ /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */ -#define vfpinstr vmovbrrd -#define vfpinstr_inst vmovbrrd_inst -#define VFPLABEL_INST VMOVBRRD_INST -#ifdef VFP_DECODE -{"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2c, 4, 4, 1}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vmovbrrd", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vmovbrrd_inst { unsigned int to_arm; unsigned int t; unsigned int t2; unsigned int m; -} vfpinstr_inst; +} vmovbrrd_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst)); + vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); inst_base->idx = index; @@ -3548,63 +2776,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VMOVBRRD_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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(vfpinstr_inst)); + INC_PC(sizeof(vmovbrrd_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_MCRR_TRANS -if (CoProc == 11 && (OPC_1 & 0xD) == 1) -{ - /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ - VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2); - return ARMul_DONE; -} -#endif -#ifdef VFP_MRRC_TRANS -if (CoProc == 11 && (OPC_1 & 0xD) == 1) -{ - /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ - VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2); - return ARMul_DONE; -} -#endif -#ifdef VFP_MRRC_IMPL -void VMOVBRRD(ARMul_State * state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword *value1, ARMword *value2) -{ - DBG("VMOV(BRRD) :\n"); - if (to_arm) - { - DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]); - *value2 = state->ExtReg[n*2+1]; - *value1 = state->ExtReg[n*2]; - } - else - { - DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1); - state->ExtReg[n*2+1] = *value2; - state->ExtReg[n*2] = *value1; - } -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vmovbrrd), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -3615,7 +2808,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -3633,9 +2826,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* LDC/STC between 2 registers and 1 double */ @@ -3645,21 +2835,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc /* ----------------------------------------------------------------------- */ /* VSTR */ /* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */ -#define vfpinstr vstr -#define vfpinstr_inst vstr_inst -#define VFPLABEL_INST VSTR_INST -#ifdef VFP_DECODE -{"vstr", 3, ARMVFP2, 24, 27, 0xd, 20, 21, 0, 9, 11, 0x5}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vstr", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vstr_inst { unsigned int single; @@ -3667,15 +2842,15 @@ typedef struct _vstr_inst { unsigned int d; unsigned int imm32; unsigned int add; -} vfpinstr_inst; +} vstr_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -3692,13 +2867,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VSTR_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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); @@ -3736,65 +2910,12 @@ VFPLABEL_INST: GOTO_NEXT_INST; } #endif -#ifdef VFP_STC_TRANS -if (P == 1 && W == 0) -{ - return VSTR(state, type, instr, value); -} -#endif -#ifdef VFP_STC_IMPL -int VSTR(ARMul_State * state, int type, ARMword instr, ARMword * value) -{ - static int i = 0; - static int single_reg, add, d, n, imm32, regs; - if (type == ARMul_FIRST) - { - single_reg = BIT(8) == 0; /* Double precision */ - add = BIT(23); /* */ - imm32 = BITS(0,7)<<2; /* may not be used */ - d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - - DBG("VSTR :\n"); - - i = 0; - regs = 1; - - return ARMul_DONE; - } - else if (type == ARMul_DATA) - { - if (single_reg) - { - *value = state->ExtReg[d+i]; - DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]); - i++; - if (i < regs) - return ARMul_INC; - else - return ARMul_DONE; - } - else - { - /* FIXME Careful of endianness, may need to rework this */ - *value = state->ExtReg[d*2+i]; - DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]); - i++; - if (i < regs*2) - return ARMul_INC; - else - return ARMul_DONE; - } - } - return -1; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vstr), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -3807,7 +2928,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -3853,43 +2974,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VPUSH */ /* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */ -#define vfpinstr vpush -#define vfpinstr_inst vpush_inst -#define VFPLABEL_INST VPUSH_INST -#ifdef VFP_DECODE -{"vpush", 3, ARMVFP2, 23, 27, 0x1a, 16, 21, 0x2d, 9, 11, 0x5}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vpush", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vpush_inst { unsigned int single; unsigned int d; unsigned int imm32; unsigned int regs; -} vfpinstr_inst; +} vpush_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst)); + vpush_inst *inst_cream = (vpush_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); inst_base->idx = index; @@ -3905,15 +3008,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VPUSH_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; int i; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vpush_inst *inst_cream = (vpush_inst *)inst_base->component; DBG("VPUSH :\n"); @@ -3958,66 +3060,11 @@ VFPLABEL_INST: GOTO_NEXT_INST; } #endif -#ifdef VFP_STC_TRANS -if (P == 1 && U == 0 && W == 1 && Rn == 0xD) -{ - return VPUSH(state, type, instr, value); -} -#endif -#ifdef VFP_STC_IMPL -int VPUSH(ARMul_State * state, int type, ARMword instr, ARMword * value) -{ - static int i = 0; - static int single_regs, add, wback, d, n, imm32, regs; - if (type == ARMul_FIRST) - { - single_regs = BIT(8) == 0; /* Single precision */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - imm32 = BITS(0,7)<<2; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */ - - DBG("VPUSH :\n"); - DBG("\tsp[%x]", state->Reg[R13]); - state->Reg[R13] = state->Reg[R13] - imm32; - DBG("=>[%x]\n", state->Reg[R13]); - - i = 0; - - return ARMul_DONE; - } - else if (type == ARMul_DATA) - { - if (single_regs) - { - *value = state->ExtReg[d + i]; - DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]); - i++; - if (i < regs) - return ARMul_INC; - else - return ARMul_DONE; - } - else - { - /* FIXME Careful of endianness, may need to rework this */ - *value = state->ExtReg[d*2 + i]; - DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]); - i++; - if (i < regs*2) - return ARMul_INC; - else - return ARMul_DONE; - } - } - - return -1; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vpush), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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); @@ -4030,7 +3077,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -4087,28 +3134,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VSTM */ /* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */ -#define vfpinstr vstm -#define vfpinstr_inst vstm_inst -#define VFPLABEL_INST VSTM_INST -#ifdef VFP_DECODE -{"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 0x5}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vstm", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vstm_inst { unsigned int single; @@ -4118,15 +3147,15 @@ typedef struct _vstm_inst { unsigned int n; unsigned int imm32; unsigned int regs; -} vfpinstr_inst; +} vstm_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -4145,15 +3174,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: /* encoding 1 */ +VSTM_INST: /* encoding 1 */ { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; int i; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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); DBG("VSTM : addr[%x]\n", addr); @@ -4203,69 +3231,12 @@ VFPLABEL_INST: /* encoding 1 */ GOTO_NEXT_INST; } #endif -#ifdef VFP_STC_TRANS -/* Should be the last operation of STC */ -return VSTM(state, type, instr, value); -#endif -#ifdef VFP_STC_IMPL -int VSTM(ARMul_State * state, int type, ARMword instr, ARMword * value) -{ - static int i = 0; - static int single_regs, add, wback, d, n, imm32, regs; - if (type == ARMul_FIRST) - { - single_regs = BIT(8) == 0; /* Single precision */ - add = BIT(23); /* */ - wback = BIT(21); /* write-back */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - imm32 = BITS(0,7) * 4; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */ - - DBG("VSTM :\n"); - - if (wback) { - state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); - DBG("\twback r%d[%x]\n", n, state->Reg[n]); - } - - i = 0; - - return ARMul_DONE; - } - else if (type == ARMul_DATA) - { - if (single_regs) - { - *value = state->ExtReg[d + i]; - DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]); - i++; - if (i < regs) - return ARMul_INC; - else - return ARMul_DONE; - } - else - { - /* FIXME Careful of endianness, may need to rework this */ - *value = state->ExtReg[d*2 + i]; - DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]); - i++; - if (i < regs*2) - return ARMul_INC; - else - return ARMul_DONE; - } - } - return -1; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vstm), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -4280,7 +3251,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -4356,43 +3327,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VPOP */ /* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */ -#define vfpinstr vpop -#define vfpinstr_inst vpop_inst -#define VFPLABEL_INST VPOP_INST -#ifdef VFP_DECODE -{"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3d, 9, 11, 0x5}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vpop", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vpop_inst { unsigned int single; unsigned int d; unsigned int imm32; unsigned int regs; -} vfpinstr_inst; +} vpop_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -4408,16 +3361,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VPOP_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; int i; unsigned int value1, value2; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + vpop_inst *inst_cream = (vpop_inst *)inst_base->component; DBG("VPOP :\n"); @@ -4468,70 +3420,12 @@ VFPLABEL_INST: GOTO_NEXT_INST; } #endif -#ifdef VFP_LDC_TRANS -if (P == 0 && U == 1 && W == 1 && Rn == 0xD) -{ - return VPOP(state, type, instr, value); -} -#endif -#ifdef VFP_LDC_IMPL -int VPOP(ARMul_State * state, int type, ARMword instr, ARMword value) -{ - static int i = 0; - static int single_regs, add, wback, d, n, imm32, regs; - if (type == ARMul_FIRST) - { - single_regs = BIT(8) == 0; /* Single precision */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - imm32 = BITS(0,7)<<2; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */ - DBG("VPOP :\n"); - DBG("\tsp[%x]", state->Reg[R13]); - state->Reg[R13] = state->Reg[R13] + imm32; - DBG("=>[%x]\n", state->Reg[R13]); - - i = 0; - - return ARMul_DONE; - } - else if (type == ARMul_TRANSFER) - { - return ARMul_DONE; - } - else if (type == ARMul_DATA) - { - if (single_regs) - { - state->ExtReg[d + i] = value; - DBG("\ts%d <= [%x]\n", d + i, value); - i++; - if (i < regs) - return ARMul_INC; - else - return ARMul_DONE; - } - else - { - /* FIXME Careful of endianness, may need to rework this */ - state->ExtReg[d*2 + i] = value; - DBG("\ts%d <= [%x]\n", d*2 + i, value); - i++; - if (i < regs*2) - return ARMul_INC; - else - return ARMul_DONE; - } - } - - return -1; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vpop), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -4547,7 +3441,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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; @@ -4611,28 +3505,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VLDR */ /* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */ -#define vfpinstr vldr -#define vfpinstr_inst vldr_inst -#define VFPLABEL_INST VLDR_INST -#ifdef VFP_DECODE -{"vldr", 3, ARMVFP2, 24, 27, 0xd, 20, 21, 0x1, 9, 11, 0x5}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vldr", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vldr_inst { unsigned int single; @@ -4640,15 +3516,15 @@ typedef struct _vldr_inst { unsigned int d; unsigned int imm32; unsigned int add; -} vfpinstr_inst; +} vldr_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -4665,13 +3541,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VLDR_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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); @@ -4710,69 +3585,12 @@ VFPLABEL_INST: GOTO_NEXT_INST; } #endif -#ifdef VFP_LDC_TRANS -if (P == 1 && W == 0) -{ - return VLDR(state, type, instr, value); -} -#endif -#ifdef VFP_LDC_IMPL -int VLDR(ARMul_State * state, int type, ARMword instr, ARMword value) -{ - static int i = 0; - static int single_reg, add, d, n, imm32, regs; - if (type == ARMul_FIRST) - { - single_reg = BIT(8) == 0; /* Double precision */ - add = BIT(23); /* */ - imm32 = BITS(0,7)<<2; /* may not be used */ - d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - - DBG("VLDR :\n"); - - i = 0; - regs = 1; - - return ARMul_DONE; - } - else if (type == ARMul_TRANSFER) - { - return ARMul_DONE; - } - else if (type == ARMul_DATA) - { - if (single_reg) - { - state->ExtReg[d+i] = value; - DBG("\ts%d <= [%x]\n", d+i, value); - i++; - if (i < regs) - return ARMul_INC; - else - return ARMul_DONE; - } - else - { - /* FIXME Careful of endianness, may need to rework this */ - state->ExtReg[d*2+i] = value; - DBG("\ts[%d] <= [%x]\n", d*2+i, value); - i++; - if (i < regs*2) - return ARMul_INC; - else - return ARMul_DONE; - } - } - return -1; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vldr), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -4788,7 +3606,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -4846,28 +3664,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST /* ----------------------------------------------------------------------- */ /* VLDM */ /* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */ -#define vfpinstr vldm -#define vfpinstr_inst vldm_inst -#define VFPLABEL_INST VLDM_INST -#ifdef VFP_DECODE -{"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 0x5}, -#endif -#ifdef VFP_DECODE_EXCLUSION -{"vldm", 0, ARMVFP2, 0}, -#endif -#ifdef VFP_INTERPRETER_TABLE -INTERPRETER_TRANSLATE(vfpinstr), -#endif -#ifdef VFP_INTERPRETER_LABEL -&&VFPLABEL_INST, -#endif #ifdef VFP_INTERPRETER_STRUCT typedef struct _vldm_inst { unsigned int single; @@ -4877,15 +3677,15 @@ typedef struct _vldm_inst { unsigned int n; unsigned int imm32; unsigned int regs; -} vfpinstr_inst; +} vldm_inst; #endif #ifdef VFP_INTERPRETER_TRANS -ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) +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(vfpinstr_inst)); - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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; @@ -4904,15 +3704,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VFPLABEL_INST: +VLDM_INST: { - INC_ICOUNTER; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; int i; - vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component; + 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); DBG("VLDM : addr[%x]\n", addr); @@ -4952,74 +3751,17 @@ VFPLABEL_INST: } cpu->Reg[15] += GET_INST_SIZE(cpu); - INC_PC(sizeof(vfpinstr_inst)); + INC_PC(sizeof(vldm_inst)); FETCH_INST; GOTO_NEXT_INST; } #endif -#ifdef VFP_LDC_TRANS -/* Should be the last operation of LDC */ -return VLDM(state, type, instr, value); -#endif -#ifdef VFP_LDC_IMPL -int VLDM(ARMul_State * state, int type, ARMword instr, ARMword value) -{ - static int i = 0; - static int single_regs, add, wback, d, n, imm32, regs; - if (type == ARMul_FIRST) - { - single_regs = BIT(8) == 0; /* Single precision */ - add = BIT(23); /* */ - wback = BIT(21); /* write-back */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - imm32 = BITS(0,7) * 4; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */ - - DBG("VLDM :\n"); - - if (wback) { - state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); - DBG("\twback r%d[%x]\n", n, state->Reg[n]); - } - - i = 0; - - return ARMul_DONE; - } - else if (type == ARMul_DATA) - { - if (single_regs) - { - state->ExtReg[d + i] = value; - DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]); - i++; - if (i < regs) - return ARMul_INC; - else - return ARMul_DONE; - } - else - { - /* FIXME Careful of endianness, may need to rework this */ - state->ExtReg[d*2 + i] = value; - DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]); - i++; - if (i < regs*2) - return ARMul_INC; - else - return ARMul_DONE; - } - } - return -1; -} -#endif #ifdef VFP_DYNCOM_TABLE -DYNCOM_FILL_ACTION(vfpinstr), +DYNCOM_FILL_ACTION(vldm), #endif #ifdef VFP_DYNCOM_TAG -int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) +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__); @@ -5034,7 +3776,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr } #endif #ifdef VFP_DYNCOM_TRANS -int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ +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); @@ -5110,14 +3852,3 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc return No_exp; } #endif -#undef vfpinstr -#undef vfpinstr_inst -#undef VFPLABEL_INST - -#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst); -#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1); -#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__); - -#define CHECK_VFP_ENABLED - -#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);} diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index 07d0c1f44..6c33d8b78 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp @@ -522,8 +522,7 @@ static s64 vfp_single_to_doubleintern(ARMul_State* state, s32 m, u32 fpscr) //ic if (tm == VFP_QNAN) vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; goto pack_nan; - } - else if (tm & VFP_ZERO) + } else if (tm & VFP_ZERO) vdd.exponent = 0; else vdd.exponent = vsm.exponent + (1023 - 127); @@ -615,12 +614,12 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f exceptions |= FPSCR_IDC; if (tm & VFP_NAN) - vsm.sign = 0; + vsm.sign = 1; if (vsm.exponent >= 127 + 32) { d = vsm.sign ? 0 : 0xffffffff; exceptions = FPSCR_IOC; - } else if (vsm.exponent >= 127 - 1) { + } else if (vsm.exponent >= 127) { int shift = 127 + 31 - vsm.exponent; u32 rem, incr = 0; @@ -705,7 +704,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f if (vsm.sign) d = ~d; exceptions |= FPSCR_IOC; - } else if (vsm.exponent >= 127 - 1) { + } else if (vsm.exponent >= 127) { int shift = 127 + 31 - vsm.exponent; u32 rem, incr = 0; @@ -1149,7 +1148,10 @@ static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) /* * Subtraction is addition with one sign inverted. */ - return vfp_single_fadd(state, sd, sn, vfp_single_packed_negate(m), fpscr); + if (m != 0x7FC00000) // Only negate if m isn't NaN. + m = vfp_single_packed_negate(m); + + return vfp_single_fadd(state, sd, sn, m, fpscr); } /* |