diff options
| author | 2014-12-29 19:47:41 -0800 | |
|---|---|---|
| committer | 2014-12-29 19:47:41 -0800 | |
| commit | 8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch) | |
| tree | f1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/arm/dyncom | |
| parent | Add comment regarding __WIN32__ in SkyEye code (diff) | |
| parent | Merge pull request #367 from bunnei/usat_ssat (diff) | |
| download | yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip | |
Fix merge conflicts
Diffstat (limited to 'src/core/arm/dyncom')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.cpp | 51 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.h | 16 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.cpp | 817 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 11064 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_run.cpp | 46 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_thumb.cpp | 863 |
8 files changed, 6273 insertions, 6588 deletions
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 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/arm/skyeye_common/armcpu.h" | 5 | #include "core/arm/skyeye_common/armcpu.h" |
| @@ -47,68 +47,38 @@ ARM_DynCom::ARM_DynCom() : ticks(0) { | |||
| 47 | ARM_DynCom::~ARM_DynCom() { | 47 | ARM_DynCom::~ARM_DynCom() { |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | /** | ||
| 51 | * Set the Program Counter to an address | ||
| 52 | * @param addr Address to set PC to | ||
| 53 | */ | ||
| 54 | void ARM_DynCom::SetPC(u32 pc) { | 50 | void ARM_DynCom::SetPC(u32 pc) { |
| 55 | state->pc = state->Reg[15] = pc; | 51 | state->pc = state->Reg[15] = pc; |
| 56 | } | 52 | } |
| 57 | 53 | ||
| 58 | /* | ||
| 59 | * Get the current Program Counter | ||
| 60 | * @return Returns current PC | ||
| 61 | */ | ||
| 62 | u32 ARM_DynCom::GetPC() const { | 54 | u32 ARM_DynCom::GetPC() const { |
| 63 | return state->Reg[15]; | 55 | return state->Reg[15]; |
| 64 | } | 56 | } |
| 65 | 57 | ||
| 66 | /** | ||
| 67 | * Get an ARM register | ||
| 68 | * @param index Register index (0-15) | ||
| 69 | * @return Returns the value in the register | ||
| 70 | */ | ||
| 71 | u32 ARM_DynCom::GetReg(int index) const { | 58 | u32 ARM_DynCom::GetReg(int index) const { |
| 72 | return state->Reg[index]; | 59 | return state->Reg[index]; |
| 73 | } | 60 | } |
| 74 | 61 | ||
| 75 | /** | ||
| 76 | * Set an ARM register | ||
| 77 | * @param index Register index (0-15) | ||
| 78 | * @param value Value to set register to | ||
| 79 | */ | ||
| 80 | void ARM_DynCom::SetReg(int index, u32 value) { | 62 | void ARM_DynCom::SetReg(int index, u32 value) { |
| 81 | state->Reg[index] = value; | 63 | state->Reg[index] = value; |
| 82 | } | 64 | } |
| 83 | 65 | ||
| 84 | /** | ||
| 85 | * Get the current CPSR register | ||
| 86 | * @return Returns the value of the CPSR register | ||
| 87 | */ | ||
| 88 | u32 ARM_DynCom::GetCPSR() const { | 66 | u32 ARM_DynCom::GetCPSR() const { |
| 89 | return state->Cpsr; | 67 | return state->Cpsr; |
| 90 | } | 68 | } |
| 91 | 69 | ||
| 92 | /** | ||
| 93 | * Set the current CPSR register | ||
| 94 | * @param cpsr Value to set CPSR to | ||
| 95 | */ | ||
| 96 | void ARM_DynCom::SetCPSR(u32 cpsr) { | 70 | void ARM_DynCom::SetCPSR(u32 cpsr) { |
| 97 | state->Cpsr = cpsr; | 71 | state->Cpsr = cpsr; |
| 98 | } | 72 | } |
| 99 | 73 | ||
| 100 | /** | ||
| 101 | * Returns the number of clock ticks since the last reset | ||
| 102 | * @return Returns number of clock ticks | ||
| 103 | */ | ||
| 104 | u64 ARM_DynCom::GetTicks() const { | 74 | u64 ARM_DynCom::GetTicks() const { |
| 105 | return ticks; | 75 | return ticks; |
| 106 | } | 76 | } |
| 107 | 77 | ||
| 108 | /** | 78 | void ARM_DynCom::AddTicks(u64 ticks) { |
| 109 | * Executes the given number of instructions | 79 | this->ticks += ticks; |
| 110 | * @param num_instructions Number of instructions to executes | 80 | } |
| 111 | */ | 81 | |
| 112 | void ARM_DynCom::ExecuteInstructions(int num_instructions) { | 82 | void ARM_DynCom::ExecuteInstructions(int num_instructions) { |
| 113 | state->NumInstrsToExecute = num_instructions; | 83 | state->NumInstrsToExecute = num_instructions; |
| 114 | 84 | ||
| @@ -118,11 +88,6 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) { | |||
| 118 | ticks += InterpreterMainLoop(state.get()); | 88 | ticks += InterpreterMainLoop(state.get()); |
| 119 | } | 89 | } |
| 120 | 90 | ||
| 121 | /** | ||
| 122 | * Saves the current CPU context | ||
| 123 | * @param ctx Thread context to save | ||
| 124 | * @todo Do we need to save Reg[15] and NextInstr? | ||
| 125 | */ | ||
| 126 | void ARM_DynCom::SaveContext(ThreadContext& ctx) { | 91 | void ARM_DynCom::SaveContext(ThreadContext& ctx) { |
| 127 | memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); | 92 | memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); |
| 128 | memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); | 93 | memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); |
| @@ -139,11 +104,6 @@ void ARM_DynCom::SaveContext(ThreadContext& ctx) { | |||
| 139 | ctx.mode = state->NextInstr; | 104 | ctx.mode = state->NextInstr; |
| 140 | } | 105 | } |
| 141 | 106 | ||
| 142 | /** | ||
| 143 | * Loads a CPU context | ||
| 144 | * @param ctx Thread context to load | ||
| 145 | * @param Do we need to load Reg[15] and NextInstr? | ||
| 146 | */ | ||
| 147 | void ARM_DynCom::LoadContext(const ThreadContext& ctx) { | 107 | void ARM_DynCom::LoadContext(const ThreadContext& ctx) { |
| 148 | memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); | 108 | memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); |
| 149 | memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); | 109 | memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); |
| @@ -160,7 +120,6 @@ void ARM_DynCom::LoadContext(const ThreadContext& ctx) { | |||
| 160 | state->NextInstr = ctx.mode; | 120 | state->NextInstr = ctx.mode; |
| 161 | } | 121 | } |
| 162 | 122 | ||
| 163 | /// Prepare core for thread reschedule (if needed to correctly handle state) | ||
| 164 | void ARM_DynCom::PrepareReschedule() { | 123 | void ARM_DynCom::PrepareReschedule() { |
| 165 | state->NumInstrsToExecute = 0; | 124 | state->NumInstrsToExecute = 0; |
| 166 | } | 125 | } |
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 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -27,14 +27,14 @@ public: | |||
| 27 | * Get the current Program Counter | 27 | * Get the current Program Counter |
| 28 | * @return Returns current PC | 28 | * @return Returns current PC |
| 29 | */ | 29 | */ |
| 30 | u32 GetPC() const; | 30 | u32 GetPC() const override; |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 33 | * Get an ARM register | 33 | * Get an ARM register |
| 34 | * @param index Register index (0-15) | 34 | * @param index Register index (0-15) |
| 35 | * @return Returns the value in the register | 35 | * @return Returns the value in the register |
| 36 | */ | 36 | */ |
| 37 | u32 GetReg(int index) const; | 37 | u32 GetReg(int index) const override; |
| 38 | 38 | ||
| 39 | /** | 39 | /** |
| 40 | * Set an ARM register | 40 | * Set an ARM register |
| @@ -47,7 +47,7 @@ public: | |||
| 47 | * Get the current CPSR register | 47 | * Get the current CPSR register |
| 48 | * @return Returns the value of the CPSR register | 48 | * @return Returns the value of the CPSR register |
| 49 | */ | 49 | */ |
| 50 | u32 GetCPSR() const; | 50 | u32 GetCPSR() const override; |
| 51 | 51 | ||
| 52 | /** | 52 | /** |
| 53 | * Set the current CPSR register | 53 | * Set the current CPSR register |
| @@ -59,7 +59,13 @@ public: | |||
| 59 | * Returns the number of clock ticks since the last reset | 59 | * Returns the number of clock ticks since the last reset |
| 60 | * @return Returns number of clock ticks | 60 | * @return Returns number of clock ticks |
| 61 | */ | 61 | */ |
| 62 | u64 GetTicks() const; | 62 | u64 GetTicks() const override; |
| 63 | |||
| 64 | /** | ||
| 65 | * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) | ||
| 66 | * @param ticks Number of ticks to advance the CPU core | ||
| 67 | */ | ||
| 68 | void AddTicks(u64 ticks) override; | ||
| 63 | 69 | ||
| 64 | /** | 70 | /** |
| 65 | * Saves the current CPU context | 71 | * 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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2012 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | ||
| 5 | * as published by the Free Software Foundation; either version 2 | ||
| 6 | * of the License, or (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_dec.cpp | ||
| 20 | * @brief Some common utility for arm decoder | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 7849 | ||
| 23 | * @date 2012-03-15 | ||
| 24 | */ | ||
| 25 | 4 | ||
| 26 | #include "core/arm/skyeye_common/arm_regformat.h" | 5 | #include "core/arm/skyeye_common/arm_regformat.h" |
| 27 | #include "core/arm/skyeye_common/armdefs.h" | 6 | #include "core/arm/skyeye_common/armdefs.h" |
| 28 | #include "core/arm/dyncom/arm_dyncom_dec.h" | 7 | #include "core/arm/dyncom/arm_dyncom_dec.h" |
| 29 | 8 | ||
| 30 | const ISEITEM arm_instruction[] = { | 9 | const ISEITEM arm_instruction[] = { |
| 31 | #define VFP_DECODE | 10 | { "vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }, |
| 32 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 11 | { "vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }, |
| 33 | #undef VFP_DECODE | 12 | { "vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }, |
| 34 | {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005}, | 13 | { "vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 35 | {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a}, | 14 | { "vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 36 | {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007}, | 15 | { "vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 37 | {"blx" , 1 , 3 , 25, 31, 0x0000007d}, | 16 | { "vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 38 | {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000}, | 17 | { "vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 39 | {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f}, | 18 | { "vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 40 | {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000}, | 19 | { "vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }, |
| 41 | {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f}, | 20 | { "vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0 }, |
| 42 | {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb}, | 21 | { "vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }, |
| 43 | {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001}, | 22 | { "vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, |
| 44 | {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007}, | 23 | { "vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }, |
| 45 | {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007}, | 24 | { "vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, |
| 46 | {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007}, | 25 | { "vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 47 | {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007}, | 26 | { "vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40 }, |
| 48 | {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007}, | 27 | { "vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }, |
| 49 | {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007}, | 28 | { "vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 5, 6, 6, 1 }, |
| 50 | {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000}, | 29 | { "vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }, |
| 51 | {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007}, | 30 | { "vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10 }, |
| 52 | {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f}, | 31 | { "vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10 }, |
| 53 | {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f}, | 32 | { "vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0, 4, 0x10 }, |
| 54 | {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005}, | 33 | { "vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10 }, |
| 55 | {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009}, | 34 | { "vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0, 4, 0x10 }, |
| 56 | {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009}, | 35 | { "vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1 }, |
| 57 | {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009}, | 36 | { "vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1 }, |
| 58 | {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009}, | 37 | { "vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11, 5 }, |
| 59 | {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007}, | 38 | { "vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11, 5 }, |
| 60 | {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003}, | 39 | { "vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 5 }, |
| 61 | {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005}, | 40 | { "vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11, 5 }, |
| 62 | {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005}, | 41 | { "vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11, 5 }, |
| 63 | {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003}, | 42 | { "vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 5 }, |
| 64 | {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009}, | 43 | |
| 65 | {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001}, | 44 | { "srs", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005 }, |
| 66 | {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b}, | 45 | { "rfe", 4, 6, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a }, |
| 67 | {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003}, | 46 | { "bkpt", 2, 3, 20, 31, 0x00000e12, 4, 7, 0x00000007 }, |
| 68 | {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009}, | 47 | { "blx", 1, 3, 25, 31, 0x0000007d }, |
| 69 | {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001}, | 48 | { "cps", 3, 6, 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000 }, |
| 70 | {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007}, | 49 | { "pld", 4, 4, 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f }, |
| 71 | {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009}, | 50 | { "setend", 2, 6, 16, 31, 0x0000f101, 4, 7, 0x00000000 }, |
| 72 | {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007}, | 51 | { "clrex", 1, 6, 0, 31, 0xf57ff01f }, |
| 73 | {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005}, | 52 | { "rev16", 2, 6, 16, 27, 0x000006bf, 4, 11, 0x000000fb }, |
| 74 | {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f}, | 53 | { "usad8", 3, 6, 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001 }, |
| 75 | {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007}, | 54 | { "sxtb", 2, 6, 16, 27, 0x000006af, 4, 7, 0x00000007 }, |
| 76 | {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003}, | 55 | { "uxtb", 2, 6, 16, 27, 0x000006ef, 4, 7, 0x00000007 }, |
| 77 | {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001}, | 56 | { "sxth", 2, 6, 16, 27, 0x000006bf, 4, 7, 0x00000007 }, |
| 78 | {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005}, | 57 | { "sxtb16", 2, 6, 16, 27, 0x0000068f, 4, 7, 0x00000007 }, |
| 79 | {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f}, | 58 | { "uxth", 2, 6, 16, 27, 0x000006ff, 4, 7, 0x00000007 }, |
| 80 | {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007}, | 59 | { "uxtb16", 2, 6, 16, 27, 0x000006cf, 4, 7, 0x00000007 }, |
| 81 | {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003}, | 60 | { "cpy", 2, 6, 20, 27, 0x0000001a, 4, 11, 0x00000000 }, |
| 82 | {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009}, | 61 | { "uxtab", 2, 6, 20, 27, 0x0000006e, 4, 9, 0x00000007 }, |
| 83 | {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001}, | 62 | { "ssub8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x0000000f }, |
| 84 | {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007}, | 63 | { "shsub8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x0000000f }, |
| 85 | {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005}, | 64 | { "ssubaddx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000005 }, |
| 86 | {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f}, | 65 | { "strex", 2, 6, 20, 27, 0x00000018, 4, 7, 0x00000009 }, |
| 87 | {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007}, | 66 | { "strexb", 2, 7, 20, 27, 0x0000001c, 4, 7, 0x00000009 }, |
| 88 | {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003}, | 67 | { "swp", 2, 0, 20, 27, 0x00000010, 4, 7, 0x00000009 }, |
| 89 | {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009}, | 68 | { "swpb", 2, 0, 20, 27, 0x00000014, 4, 7, 0x00000009 }, |
| 90 | {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001}, | 69 | { "ssub16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000007 }, |
| 91 | {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003}, | 70 | { "ssat16", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000003 }, |
| 92 | {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009}, | 71 | { "shsubaddx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000005 }, |
| 93 | {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001}, | 72 | { "qsubaddx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000005 }, |
| 94 | {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007}, | 73 | { "shaddsubx", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000003 }, |
| 95 | {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007}, | 74 | { "shadd8", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000009 }, |
| 96 | {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009}, | 75 | { "shadd16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000001 }, |
| 97 | {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002}, | 76 | { "sel", 2, 6, 20, 27, 0x00000068, 4, 7, 0x0000000b }, |
| 98 | {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001}, | 77 | { "saddsubx", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000003 }, |
| 99 | {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007}, | 78 | { "sadd8", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000009 }, |
| 100 | {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001}, | 79 | { "sadd16", 2, 6, 20, 27, 0x00000061, 4, 7, 0x00000001 }, |
| 101 | {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003}, | 80 | { "shsub16", 2, 6, 20, 27, 0x00000063, 4, 7, 0x00000007 }, |
| 102 | {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003}, | 81 | { "umaal", 2, 6, 20, 27, 0x00000004, 4, 7, 0x00000009 }, |
| 103 | {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b}, | 82 | { "uxtab16", 2, 6, 20, 27, 0x0000006c, 4, 7, 0x00000007 }, |
| 104 | {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005}, | 83 | { "usubaddx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000005 }, |
| 105 | {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001}, | 84 | { "usub8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x0000000f }, |
| 106 | {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003}, | 85 | { "usub16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000007 }, |
| 107 | {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009}, | 86 | { "usat16", 2, 6, 20, 27, 0x0000006e, 4, 7, 0x00000003 }, |
| 108 | {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005}, | 87 | { "usada8", 2, 6, 20, 27, 0x00000078, 4, 7, 0x00000001 }, |
| 109 | {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005}, | 88 | { "uqsubaddx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000005 }, |
| 110 | {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005}, | 89 | { "uqsub8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x0000000f }, |
| 111 | {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009}, | 90 | { "uqsub16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000007 }, |
| 112 | {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f}, | 91 | { "uqaddsubx", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000003 }, |
| 113 | {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007}, | 92 | { "uqadd8", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000009 }, |
| 114 | {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 93 | { "uqadd16", 2, 6, 20, 27, 0x00000066, 4, 7, 0x00000001 }, |
| 115 | {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 94 | { "sxtab", 2, 6, 20, 27, 0x0000006a, 4, 7, 0x00000007 }, |
| 116 | {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001}, | 95 | { "uhsubaddx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000005 }, |
| 117 | {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001}, | 96 | { "uhsub8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x0000000f }, |
| 118 | {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001}, | 97 | { "uhsub16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000007 }, |
| 119 | {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 98 | { "uhaddsubx", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000003 }, |
| 120 | {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001}, | 99 | { "uhadd8", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000009 }, |
| 121 | {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 100 | { "uhadd16", 2, 6, 20, 27, 0x00000067, 4, 7, 0x00000001 }, |
| 122 | {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001}, | 101 | { "uaddsubx", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000003 }, |
| 123 | {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000}, | 102 | { "uadd8", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000009 }, |
| 124 | {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002}, | 103 | { "uadd16", 2, 6, 20, 27, 0x00000065, 4, 7, 0x00000001 }, |
| 125 | {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005}, | 104 | { "sxtah", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000007 }, |
| 126 | {"pkhbt" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000001}, | 105 | { "sxtab16", 2, 6, 20, 27, 0x00000068, 4, 7, 0x00000007 }, |
| 127 | {"smul" , 3 , 4 , 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000}, | 106 | { "qadd8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000009 }, |
| 128 | {"smlalxy" , 3 , 4 , 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000}, | 107 | { "bxj", 2, 5, 20, 27, 0x00000012, 4, 7, 0x00000002 }, |
| 129 | // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, | 108 | { "clz", 2, 3, 20, 27, 0x00000016, 4, 7, 0x00000001 }, |
| 130 | {"smla" , 3 , 4 , 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000}, | 109 | { "uxtah", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x00000007 }, |
| 131 | {"mcrr" , 1 , 6 , 20, 27, 0x000000c4}, | 110 | { "bx", 2, 2, 20, 27, 0x00000012, 4, 7, 0x00000001 }, |
| 132 | {"mrrc" , 1 , 6 , 20, 27, 0x000000c5}, | 111 | { "rev", 2, 6, 20, 27, 0x0000006b, 4, 7, 0x00000003 }, |
| 133 | {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015}, | 112 | { "blx", 2, 3, 20, 27, 0x00000012, 4, 7, 0x00000003 }, |
| 134 | {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011}, | 113 | { "revsh", 2, 6, 20, 27, 0x0000006f, 4, 7, 0x0000000b }, |
| 135 | {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013}, | 114 | { "qadd", 2, 4, 20, 27, 0x00000010, 4, 7, 0x00000005 }, |
| 136 | {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017}, | 115 | { "qadd16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000001 }, |
| 137 | {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009}, | 116 | { "qaddsubx", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000003 }, |
| 138 | {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009}, | 117 | { "ldrex", 2, 0, 20, 27, 0x00000019, 4, 7, 0x00000009 }, |
| 139 | {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009}, | 118 | { "qdadd", 2, 4, 20, 27, 0x00000014, 4, 7, 0x00000005 }, |
| 140 | {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009}, | 119 | { "qdsub", 2, 4, 20, 27, 0x00000016, 4, 7, 0x00000005 }, |
| 141 | {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009}, | 120 | { "qsub", 2, 4, 20, 27, 0x00000012, 4, 7, 0x00000005 }, |
| 142 | {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009}, | 121 | { "ldrexb", 2, 7, 20, 27, 0x0000001d, 4, 7, 0x00000009 }, |
| 143 | {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001}, | 122 | { "qsub8", 2, 6, 20, 27, 0x00000062, 4, 7, 0x0000000f }, |
| 144 | {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001}, | 123 | { "qsub16", 2, 6, 20, 27, 0x00000062, 4, 7, 0x00000007 }, |
| 145 | {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000}, | 124 | { "smuad", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 146 | {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000}, | 125 | { "smmul", 4, 6, 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 147 | {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000}, | 126 | { "smusd", 4, 6, 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001 }, |
| 148 | {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e}, | 127 | { "smlsd", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001 }, |
| 149 | {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000}, | 128 | { "smlsld", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001 }, |
| 150 | {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001}, | 129 | { "smmla", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 151 | {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004}, | 130 | { "smmls", 3, 6, 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001 }, |
| 152 | {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003}, | 131 | { "smlald", 3, 6, 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 153 | {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007}, | 132 | { "smlad", 3, 6, 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001 }, |
| 154 | {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006}, | 133 | { "smlaw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000 }, |
| 155 | {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005}, | 134 | { "smulw", 3, 4, 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002 }, |
| 156 | {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002}, | 135 | { "pkhtb", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000005 }, |
| 157 | {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c}, | 136 | { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 }, |
| 158 | {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f}, | 137 | { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 159 | {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d}, | 138 | { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 160 | {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004}, | 139 | // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, |
| 161 | {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001}, | 140 | { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 162 | {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f}, | 141 | { "mcrr", 1, 6, 20, 27, 0x000000c4 }, |
| 163 | {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000}, | 142 | { "mrrc", 1, 6, 20, 27, 0x000000c5 }, |
| 164 | {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001}, | 143 | { "cmp", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000015 }, |
| 165 | {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d}, | 144 | { "tst", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000011 }, |
| 166 | {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f}, | 145 | { "teq", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000013 }, |
| 167 | {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b}, | 146 | { "cmn", 2, 0, 26, 27, 0x00000000, 20, 24, 0x00000017 }, |
| 168 | {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b}, | 147 | { "smull", 2, 0, 21, 27, 0x00000006, 4, 7, 0x00000009 }, |
| 169 | {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d}, | 148 | { "umull", 2, 0, 21, 27, 0x00000004, 4, 7, 0x00000009 }, |
| 170 | {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002}, | 149 | { "umlal", 2, 0, 21, 27, 0x00000005, 4, 7, 0x00000009 }, |
| 171 | {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006}, | 150 | { "smlal", 2, 0, 21, 27, 0x00000007, 4, 7, 0x00000009 }, |
| 172 | {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007}, | 151 | { "mul", 2, 0, 21, 27, 0x00000000, 4, 7, 0x00000009 }, |
| 173 | {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003}, | 152 | { "mla", 2, 0, 21, 27, 0x00000001, 4, 7, 0x00000009 }, |
| 174 | {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001}, | 153 | { "ssat", 2, 6, 21, 27, 0x00000035, 4, 5, 0x00000001 }, |
| 175 | {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001}, | 154 | { "usat", 2, 6, 21, 27, 0x00000037, 4, 5, 0x00000001 }, |
| 176 | {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002}, | 155 | { "mrs", 4, 0, 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000 }, |
| 177 | {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001}, | 156 | { "msr", 3, 0, 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000 }, |
| 178 | {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000}, | 157 | { "and", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000000 }, |
| 179 | {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, | 158 | { "bic", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000e }, |
| 180 | {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001}, | 159 | { "ldm", 3, 0, 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000 }, |
| 181 | {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000}, | 160 | { "eor", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000001 }, |
| 182 | {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000}, | 161 | { "add", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000004 }, |
| 183 | {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000}, | 162 | { "rsb", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000003 }, |
| 184 | {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001}, | 163 | { "rsc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000007 }, |
| 185 | {"swi" , 1 , 0 , 24, 27, 0x0000000f}, | 164 | { "sbc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000006 }, |
| 186 | {"bbl" , 1 , 0 , 25, 27, 0x00000005}, | 165 | { "adc", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000005 }, |
| 166 | { "sub", 2, 0, 26, 27, 0x00000000, 21, 24, 0x00000002 }, | ||
| 167 | { "orr", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000c }, | ||
| 168 | { "mvn", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000f }, | ||
| 169 | { "mov", 2, 0, 26, 27, 0x00000000, 21, 24, 0x0000000d }, | ||
| 170 | { "stm", 2, 0, 25, 27, 0x00000004, 20, 22, 0x00000004 }, | ||
| 171 | { "ldm", 4, 0, 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001 }, | ||
| 172 | { "ldrsh", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f }, | ||
| 173 | { "stm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000 }, | ||
| 174 | { "ldm", 3, 0, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001 }, | ||
| 175 | { "ldrsb", 3, 2, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d }, | ||
| 176 | { "strd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f }, | ||
| 177 | { "ldrh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b }, | ||
| 178 | { "strh", 3, 0, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b }, | ||
| 179 | { "ldrd", 3, 4, 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d }, | ||
| 180 | { "strt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002 }, | ||
| 181 | { "strbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006 }, | ||
| 182 | { "ldrbt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007 }, | ||
| 183 | { "ldrt", 3, 0, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003 }, | ||
| 184 | { "mrc", 3, 6, 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001 }, | ||
| 185 | { "mcr", 3, 0, 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001 }, | ||
| 186 | { "msr", 2, 0, 23, 27, 0x00000006, 20, 21, 0x00000002 }, | ||
| 187 | { "ldrb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001 }, | ||
| 188 | { "strb", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000 }, | ||
| 189 | { "ldr", 4, 0, 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }, | ||
| 190 | { "ldrcond", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }, | ||
| 191 | { "str", 3, 0, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000 }, | ||
| 192 | { "cdp", 2, 0, 24, 27, 0x0000000e, 4, 4, 0x00000000 }, | ||
| 193 | { "stc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000000 }, | ||
| 194 | { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, | ||
| 195 | { "swi", 1, 0, 24, 27, 0x0000000f }, | ||
| 196 | { "bbl", 1, 0, 25, 27, 0x00000005 }, | ||
| 187 | }; | 197 | }; |
| 188 | 198 | ||
| 189 | const ISEITEM arm_exclusion_code[] = { | 199 | const ISEITEM arm_exclusion_code[] = { |
| 190 | #define VFP_DECODE_EXCLUSION | 200 | { "vmla", 0, ARMVFP2, 0 }, |
| 191 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 201 | { "vmls", 0, ARMVFP2, 0 }, |
| 192 | #undef VFP_DECODE_EXCLUSION | 202 | { "vnmla", 0, ARMVFP2, 0 }, |
| 193 | {"srs" , 0 , 6 , 0}, | 203 | { "vnmla", 0, ARMVFP2, 0 }, |
| 194 | {"rfe" , 0 , 6 , 0}, | 204 | { "vnmls", 0, ARMVFP2, 0 }, |
| 195 | {"bkpt" , 0 , 3 , 0}, | 205 | { "vnmul", 0, ARMVFP2, 0 }, |
| 196 | {"blx" , 0 , 3 , 0}, | 206 | { "vmul", 0, ARMVFP2, 0 }, |
| 197 | {"cps" , 0 , 6 , 0}, | 207 | { "vadd", 0, ARMVFP2, 0 }, |
| 198 | {"pld" , 0 , 4 , 0}, | 208 | { "vsub", 0, ARMVFP2, 0 }, |
| 199 | {"setend" , 0 , 6 , 0}, | 209 | { "vdiv", 0, ARMVFP2, 0 }, |
| 200 | {"clrex" , 0 , 6 , 0}, | 210 | { "vmov(i)", 0, ARMVFP3, 0 }, |
| 201 | {"rev16" , 0 , 6 , 0}, | 211 | { "vmov(r)", 0, ARMVFP3, 0 }, |
| 202 | {"usad8" , 0 , 6 , 0}, | 212 | { "vabs", 0, ARMVFP2, 0 }, |
| 203 | {"sxtb" , 0 , 6 , 0}, | 213 | { "vneg", 0, ARMVFP2, 0 }, |
| 204 | {"uxtb" , 0 , 6 , 0}, | 214 | { "vsqrt", 0, ARMVFP2, 0 }, |
| 205 | {"sxth" , 0 , 6 , 0}, | 215 | { "vcmp", 0, ARMVFP2, 0 }, |
| 206 | {"sxtb16" , 0 , 6 , 0}, | 216 | { "vcmp2", 0, ARMVFP2, 0 }, |
| 207 | {"uxth" , 0 , 6 , 0}, | 217 | { "vcvt(bff)", 0, ARMVFP3, 4, 4, 1 }, |
| 208 | {"uxtb16" , 0 , 6 , 0}, | 218 | { "vcvt(bds)", 0, ARMVFP2, 0 }, |
| 209 | {"cpy" , 0 , 6 , 0}, | 219 | { "vcvt(bfi)", 0, ARMVFP2, 0 }, |
| 210 | {"uxtab" , 0 , 6 , 0}, | 220 | { "vmovbrs", 0, ARMVFP2, 0 }, |
| 211 | {"ssub8" , 0 , 6 , 0}, | 221 | { "vmsr", 0, ARMVFP2, 0 }, |
| 212 | {"shsub8" , 0 , 6 , 0}, | 222 | { "vmovbrc", 0, ARMVFP2, 0 }, |
| 213 | {"ssubaddx" , 0 , 6 , 0}, | 223 | { "vmrs", 0, ARMVFP2, 0 }, |
| 214 | {"strex" , 0 , 6 , 0}, | 224 | { "vmovbcr", 0, ARMVFP2, 0 }, |
| 215 | {"strexb" , 0 , 7 , 0}, | 225 | { "vmovbrrss", 0, ARMVFP2, 0 }, |
| 216 | {"swp" , 0 , 0 , 0}, | 226 | { "vmovbrrd", 0, ARMVFP2, 0 }, |
| 217 | {"swpb" , 0 , 0 , 0}, | 227 | { "vstr", 0, ARMVFP2, 0 }, |
| 218 | {"ssub16" , 0 , 6 , 0}, | 228 | { "vpush", 0, ARMVFP2, 0 }, |
| 219 | {"ssat16" , 0 , 6 , 0}, | 229 | { "vstm", 0, ARMVFP2, 0 }, |
| 220 | {"shsubaddx" , 0 , 6 , 0}, | 230 | { "vpop", 0, ARMVFP2, 0 }, |
| 221 | {"qsubaddx" , 0 , 6 , 0}, | 231 | { "vldr", 0, ARMVFP2, 0 }, |
| 222 | {"shaddsubx" , 0 , 6 , 0}, | 232 | { "vldm", 0, ARMVFP2, 0 }, |
| 223 | {"shadd8" , 0 , 6 , 0}, | 233 | |
| 224 | {"shadd16" , 0 , 6 , 0}, | 234 | { "srs", 0, 6, 0 }, |
| 225 | {"sel" , 0 , 6 , 0}, | 235 | { "rfe", 0, 6, 0 }, |
| 226 | {"saddsubx" , 0 , 6 , 0}, | 236 | { "bkpt", 0, 3, 0 }, |
| 227 | {"sadd8" , 0 , 6 , 0}, | 237 | { "blx", 0, 3, 0 }, |
| 228 | {"sadd16" , 0 , 6 , 0}, | 238 | { "cps", 0, 6, 0 }, |
| 229 | {"shsub16" , 0 , 6 , 0}, | 239 | { "pld", 0, 4, 0 }, |
| 230 | {"umaal" , 0 , 6 , 0}, | 240 | { "setend", 0, 6, 0 }, |
| 231 | {"uxtab16" , 0 , 6 , 0}, | 241 | { "clrex", 0, 6, 0 }, |
| 232 | {"usubaddx" , 0 , 6 , 0}, | 242 | { "rev16", 0, 6, 0 }, |
| 233 | {"usub8" , 0 , 6 , 0}, | 243 | { "usad8", 0, 6, 0 }, |
| 234 | {"usub16" , 0 , 6 , 0}, | 244 | { "sxtb", 0, 6, 0 }, |
| 235 | {"usat16" , 0 , 6 , 0}, | 245 | { "uxtb", 0, 6, 0 }, |
| 236 | {"usada8" , 0 , 6 , 0}, | 246 | { "sxth", 0, 6, 0 }, |
| 237 | {"uqsubaddx" , 0 , 6 , 0}, | 247 | { "sxtb16", 0, 6, 0 }, |
| 238 | {"uqsub8" , 0 , 6 , 0}, | 248 | { "uxth", 0, 6, 0 }, |
| 239 | {"uqsub16" , 0 , 6 , 0}, | 249 | { "uxtb16", 0, 6, 0 }, |
| 240 | {"uqaddsubx" , 0 , 6 , 0}, | 250 | { "cpy", 0, 6, 0 }, |
| 241 | {"uqadd8" , 0 , 6 , 0}, | 251 | { "uxtab", 0, 6, 0 }, |
| 242 | {"uqadd16" , 0 , 6 , 0}, | 252 | { "ssub8", 0, 6, 0 }, |
| 243 | {"sxtab" , 0 , 6 , 0}, | 253 | { "shsub8", 0, 6, 0 }, |
| 244 | {"uhsubaddx" , 0 , 6 , 0}, | 254 | { "ssubaddx", 0, 6, 0 }, |
| 245 | {"uhsub8" , 0 , 6 , 0}, | 255 | { "strex", 0, 6, 0 }, |
| 246 | {"uhsub16" , 0 , 6 , 0}, | 256 | { "strexb", 0, 7, 0 }, |
| 247 | {"uhaddsubx" , 0 , 6 , 0}, | 257 | { "swp", 0, 0, 0 }, |
| 248 | {"uhadd8" , 0 , 6 , 0}, | 258 | { "swpb", 0, 0, 0 }, |
| 249 | {"uhadd16" , 0 , 6 , 0}, | 259 | { "ssub16", 0, 6, 0 }, |
| 250 | {"uaddsubx" , 0 , 6 , 0}, | 260 | { "ssat16", 0, 6, 0 }, |
| 251 | {"uadd8" , 0 , 6 , 0}, | 261 | { "shsubaddx", 0, 6, 0 }, |
| 252 | {"uadd16" , 0 , 6 , 0}, | 262 | { "qsubaddx", 0, 6, 0 }, |
| 253 | {"sxtah" , 0 , 6 , 0}, | 263 | { "shaddsubx", 0, 6, 0 }, |
| 254 | {"sxtab16" , 0 , 6 , 0}, | 264 | { "shadd8", 0, 6, 0 }, |
| 255 | {"qadd8" , 0 , 6 , 0}, | 265 | { "shadd16", 0, 6, 0 }, |
| 256 | {"bxj" , 0 , 5 , 0}, | 266 | { "sel", 0, 6, 0 }, |
| 257 | {"clz" , 0 , 3 , 0}, | 267 | { "saddsubx", 0, 6, 0 }, |
| 258 | {"uxtah" , 0 , 6 , 0}, | 268 | { "sadd8", 0, 6, 0 }, |
| 259 | {"bx" , 0 , 2 , 0}, | 269 | { "sadd16", 0, 6, 0 }, |
| 260 | {"rev" , 0 , 6 , 0}, | 270 | { "shsub16", 0, 6, 0 }, |
| 261 | {"blx" , 0 , 3 , 0}, | 271 | { "umaal", 0, 6, 0 }, |
| 262 | {"revsh" , 0 , 6 , 0}, | 272 | { "uxtab16", 0, 6, 0 }, |
| 263 | {"qadd" , 0 , 4 , 0}, | 273 | { "usubaddx", 0, 6, 0 }, |
| 264 | {"qadd16" , 0 , 6 , 0}, | 274 | { "usub8", 0, 6, 0 }, |
| 265 | {"qaddsubx" , 0 , 6 , 0}, | 275 | { "usub16", 0, 6, 0 }, |
| 266 | {"ldrex" , 0 , 0 , 0}, | 276 | { "usat16", 0, 6, 0 }, |
| 267 | {"qdadd" , 0 , 4 , 0}, | 277 | { "usada8", 0, 6, 0 }, |
| 268 | {"qdsub" , 0 , 4 , 0}, | 278 | { "uqsubaddx", 0, 6, 0 }, |
| 269 | {"qsub" , 0 , 4 , 0}, | 279 | { "uqsub8", 0, 6, 0 }, |
| 270 | {"ldrexb" , 0 , 7 , 0}, | 280 | { "uqsub16", 0, 6, 0 }, |
| 271 | {"qsub8" , 0 , 6 , 0}, | 281 | { "uqaddsubx", 0, 6, 0 }, |
| 272 | {"qsub16" , 0 , 6 , 0}, | 282 | { "uqadd8", 0, 6, 0 }, |
| 273 | {"smuad" , 0 , 6 , 0}, | 283 | { "uqadd16", 0, 6, 0 }, |
| 274 | {"smmul" , 0 , 6 , 0}, | 284 | { "sxtab", 0, 6, 0 }, |
| 275 | {"smusd" , 0 , 6 , 0}, | 285 | { "uhsubaddx", 0, 6, 0 }, |
| 276 | {"smlsd" , 0 , 6 , 0}, | 286 | { "uhsub8", 0, 6, 0 }, |
| 277 | {"smlsld" , 0 , 6 , 0}, | 287 | { "uhsub16", 0, 6, 0 }, |
| 278 | {"smmla" , 0 , 6 , 0}, | 288 | { "uhaddsubx", 0, 6, 0 }, |
| 279 | {"smmls" , 0 , 6 , 0}, | 289 | { "uhadd8", 0, 6, 0 }, |
| 280 | {"smlald" , 0 , 6 , 0}, | 290 | { "uhadd16", 0, 6, 0 }, |
| 281 | {"smlad" , 0 , 6 , 0}, | 291 | { "uaddsubx", 0, 6, 0 }, |
| 282 | {"smlaw" , 0 , 4 , 0}, | 292 | { "uadd8", 0, 6, 0 }, |
| 283 | {"smulw" , 0 , 4 , 0}, | 293 | { "uadd16", 0, 6, 0 }, |
| 284 | {"pkhtb" , 0 , 6 , 0}, | 294 | { "sxtah", 0, 6, 0 }, |
| 285 | {"pkhbt" , 0 , 6 , 0}, | 295 | { "sxtab16", 0, 6, 0 }, |
| 286 | {"smul" , 0 , 4 , 0}, | 296 | { "qadd8", 0, 6, 0 }, |
| 287 | {"smlal" , 0 , 4 , 0}, | 297 | { "bxj", 0, 5, 0 }, |
| 288 | {"smla" , 0 , 4 , 0}, | 298 | { "clz", 0, 3, 0 }, |
| 289 | {"mcrr" , 0 , 6 , 0}, | 299 | { "uxtah", 0, 6, 0 }, |
| 290 | {"mrrc" , 0 , 6 , 0}, | 300 | { "bx", 0, 2, 0 }, |
| 291 | {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 301 | { "rev", 0, 6, 0 }, |
| 292 | {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 302 | { "blx", 0, 3, 0 }, |
| 293 | {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 303 | { "revsh", 0, 6, 0 }, |
| 294 | {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 304 | { "qadd", 0, 4, 0 }, |
| 295 | {"smull" , 0 , 0 , 0}, | 305 | { "qadd16", 0, 6, 0 }, |
| 296 | {"umull" , 0 , 0 , 0}, | 306 | { "qaddsubx", 0, 6, 0 }, |
| 297 | {"umlal" , 0 , 0 , 0}, | 307 | { "ldrex", 0, 0, 0 }, |
| 298 | {"smlal" , 0 , 0 , 0}, | 308 | { "qdadd", 0, 4, 0 }, |
| 299 | {"mul" , 0 , 0 , 0}, | 309 | { "qdsub", 0, 4, 0 }, |
| 300 | {"mla" , 0 , 0 , 0}, | 310 | { "qsub", 0, 4, 0 }, |
| 301 | {"ssat" , 0 , 6 , 0}, | 311 | { "ldrexb", 0, 7, 0 }, |
| 302 | {"usat" , 0 , 6 , 0}, | 312 | { "qsub8", 0, 6, 0 }, |
| 303 | {"mrs" , 0 , 0 , 0}, | 313 | { "qsub16", 0, 6, 0 }, |
| 304 | {"msr" , 0 , 0 , 0}, | 314 | { "smuad", 0, 6, 0 }, |
| 305 | {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 315 | { "smmul", 0, 6, 0 }, |
| 306 | {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 316 | { "smusd", 0, 6, 0 }, |
| 307 | {"ldm" , 0 , 0 , 0}, | 317 | { "smlsd", 0, 6, 0 }, |
| 308 | {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 318 | { "smlsld", 0, 6, 0 }, |
| 309 | {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 319 | { "smmla", 0, 6, 0 }, |
| 310 | {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 320 | { "smmls", 0, 6, 0 }, |
| 311 | {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 321 | { "smlald", 0, 6, 0 }, |
| 312 | {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 322 | { "smlad", 0, 6, 0 }, |
| 313 | {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 323 | { "smlaw", 0, 4, 0 }, |
| 314 | {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 324 | { "smulw", 0, 4, 0 }, |
| 315 | {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 325 | { "pkhtb", 0, 6, 0 }, |
| 316 | {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 326 | { "pkhbt", 0, 6, 0 }, |
| 317 | {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000}, | 327 | { "smul", 0, 4, 0 }, |
| 318 | {"stm" , 0 , 0 , 0}, | 328 | { "smlal", 0, 4, 0 }, |
| 319 | {"ldm" , 0 , 0 , 0}, | 329 | { "smla", 0, 4, 0 }, |
| 320 | {"ldrsh" , 0 , 2 , 0}, | 330 | { "mcrr", 0, 6, 0 }, |
| 321 | {"stm" , 0 , 0 , 0}, | 331 | { "mrrc", 0, 6, 0 }, |
| 322 | {"ldm" , 0 , 0 , 0}, | 332 | { "cmp", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 323 | {"ldrsb" , 0 , 2 , 0}, | 333 | { "tst", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 324 | {"strd" , 0 , 4 , 0}, | 334 | { "teq", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 325 | {"ldrh" , 0 , 0 , 0}, | 335 | { "cmn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 326 | {"strh" , 0 , 0 , 0}, | 336 | { "smull", 0, 0, 0 }, |
| 327 | {"ldrd" , 0 , 4 , 0}, | 337 | { "umull", 0, 0, 0 }, |
| 328 | {"strt" , 0 , 0 , 0}, | 338 | { "umlal", 0, 0, 0 }, |
| 329 | {"strbt" , 0 , 0 , 0}, | 339 | { "smlal", 0, 0, 0 }, |
| 330 | {"ldrbt" , 0 , 0 , 0}, | 340 | { "mul", 0, 0, 0 }, |
| 331 | {"ldrt" , 0 , 0 , 0}, | 341 | { "mla", 0, 0, 0 }, |
| 332 | {"mrc" , 0 , 6 , 0}, | 342 | { "ssat", 0, 6, 0 }, |
| 333 | {"mcr" , 0 , 0 , 0}, | 343 | { "usat", 0, 6, 0 }, |
| 334 | {"msr" , 0 , 0 , 0}, | 344 | { "mrs", 0, 0, 0 }, |
| 335 | {"ldrb" , 0 , 0 , 0}, | 345 | { "msr", 0, 0, 0 }, |
| 336 | {"strb" , 0 , 0 , 0}, | 346 | { "and", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 337 | {"ldr" , 0 , 0 , 0}, | 347 | { "bic", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 338 | {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e}, | 348 | { "ldm", 0, 0, 0 }, |
| 339 | {"str" , 0 , 0 , 0}, | 349 | { "eor", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 340 | {"cdp" , 0 , 0 , 0}, | 350 | { "add", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 341 | {"stc" , 0 , 0 , 0}, | 351 | { "rsb", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 342 | {"ldc" , 0 , 0 , 0}, | 352 | { "rsc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 343 | {"swi" , 0 , 0 , 0}, | 353 | { "sbc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 344 | {"bbl" , 0 , 0 , 0}, | 354 | { "adc", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 345 | {"bl_1_thumb", 0, INVALID, 0},/* should be table[-4] */ | 355 | { "sub", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 346 | {"bl_2_thumb", 0, INVALID, 0}, /* should be located at the end of the table[-3] */ | 356 | { "orr", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 347 | {"blx_1_thumb", 0, INVALID, 0}, /* should be located at table[-2] */ | 357 | { "mvn", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 348 | {"invalid", 0, INVALID, 0} | 358 | { "mov", 3, 0, 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }, |
| 359 | { "stm", 0, 0, 0 }, | ||
| 360 | { "ldm", 0, 0, 0 }, | ||
| 361 | { "ldrsh", 0, 2, 0 }, | ||
| 362 | { "stm", 0, 0, 0 }, | ||
| 363 | { "ldm", 0, 0, 0 }, | ||
| 364 | { "ldrsb", 0, 2, 0 }, | ||
| 365 | { "strd", 0, 4, 0 }, | ||
| 366 | { "ldrh", 0, 0, 0 }, | ||
| 367 | { "strh", 0, 0, 0 }, | ||
| 368 | { "ldrd", 0, 4, 0 }, | ||
| 369 | { "strt", 0, 0, 0 }, | ||
| 370 | { "strbt", 0, 0, 0 }, | ||
| 371 | { "ldrbt", 0, 0, 0 }, | ||
| 372 | { "ldrt", 0, 0, 0 }, | ||
| 373 | { "mrc", 0, 6, 0 }, | ||
| 374 | { "mcr", 0, 0, 0 }, | ||
| 375 | { "msr", 0, 0, 0 }, | ||
| 376 | { "ldrb", 0, 0, 0 }, | ||
| 377 | { "strb", 0, 0, 0 }, | ||
| 378 | { "ldr", 0, 0, 0 }, | ||
| 379 | { "ldrcond", 1, 0, 28, 31, 0x0000000e }, | ||
| 380 | { "str", 0, 0, 0 }, | ||
| 381 | { "cdp", 0, 0, 0 }, | ||
| 382 | { "stc", 0, 0, 0 }, | ||
| 383 | { "ldc", 0, 0, 0 }, | ||
| 384 | { "swi", 0, 0, 0 }, | ||
| 385 | { "bbl", 0, 0, 0 }, | ||
| 386 | { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4] | ||
| 387 | { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3] | ||
| 388 | { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2] | ||
| 389 | { "invalid", 0, INVALID, 0 } | ||
| 349 | }; | 390 | }; |
| 350 | 391 | ||
| 351 | int decode_arm_instr(uint32_t instr, int32_t *idx) | 392 | int decode_arm_instr(uint32_t instr, int32_t *idx) { |
| 352 | { | 393 | int n = 0; |
| 353 | int n = 0; | 394 | int base = 0; |
| 354 | int base = 0; | 395 | int ret = DECODE_FAILURE; |
| 355 | int ret = DECODE_FAILURE; | 396 | int i = 0; |
| 356 | int i = 0; | 397 | int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); |
| 357 | int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM); | 398 | for (i = 0; i < instr_slots; i++) { |
| 358 | for (i = 0; i < instr_slots; i++) | 399 | n = arm_instruction[i].attribute_value; |
| 359 | { | 400 | base = 0; |
| 360 | // ret = DECODE_SUCCESS; | ||
| 361 | n = arm_instruction[i].attribute_value; | ||
| 362 | base = 0; | ||
| 363 | while (n) { | ||
| 364 | if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { | ||
| 365 | /* clrex */ | ||
| 366 | if (instr != arm_instruction[i].content[base + 2]) { | ||
| 367 | break; | ||
| 368 | } | ||
| 369 | } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { | ||
| 370 | break; | ||
| 371 | } | ||
| 372 | base += 3; | ||
| 373 | n --; | ||
| 374 | } | ||
| 375 | //All conditions is satisfied. | ||
| 376 | if (n == 0) | ||
| 377 | ret = DECODE_SUCCESS; | ||
| 378 | 401 | ||
| 379 | if (ret == DECODE_SUCCESS) { | 402 | while (n) { |
| 380 | n = arm_exclusion_code[i].attribute_value; | 403 | if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { |
| 381 | if (n != 0) { | 404 | // clrex |
| 382 | base = 0; | 405 | if (instr != arm_instruction[i].content[base + 2]) { |
| 383 | while (n) { | 406 | break; |
| 384 | if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { | 407 | } |
| 385 | break; } | 408 | } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { |
| 386 | base += 3; | 409 | break; |
| 387 | n --; | 410 | } |
| 388 | } | 411 | base += 3; |
| 389 | //All conditions is satisfied. | 412 | n--; |
| 390 | if (n == 0) | 413 | } |
| 391 | ret = DECODE_FAILURE; | ||
| 392 | } | ||
| 393 | } | ||
| 394 | 414 | ||
| 395 | if (ret == DECODE_SUCCESS) { | 415 | // All conditions is satisfied. |
| 396 | *idx = i; | 416 | if (n == 0) |
| 397 | return ret; | 417 | ret = DECODE_SUCCESS; |
| 398 | } | ||
| 399 | } | ||
| 400 | return ret; | ||
| 401 | } | ||
| 402 | 418 | ||
| 419 | if (ret == DECODE_SUCCESS) { | ||
| 420 | n = arm_exclusion_code[i].attribute_value; | ||
| 421 | if (n != 0) { | ||
| 422 | base = 0; | ||
| 423 | while (n) { | ||
| 424 | if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | base += 3; | ||
| 428 | n--; | ||
| 429 | } | ||
| 430 | |||
| 431 | // All conditions is satisfied. | ||
| 432 | if (n == 0) | ||
| 433 | ret = DECODE_FAILURE; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | if (ret == DECODE_SUCCESS) { | ||
| 438 | *idx = i; | ||
| 439 | return ret; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | return ret; | ||
| 443 | } | ||
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 @@ | |||
| 56 | #define RN ((instr >> 16) & 0xF) | 56 | #define RN ((instr >> 16) & 0xF) |
| 57 | /*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */ | 57 | /*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */ |
| 58 | #define RM (instr & 0xF) | 58 | #define RM (instr & 0xF) |
| 59 | #define BIT(n) ((instr >> (n)) & 1) | ||
| 60 | #define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) | ||
| 61 | 59 | ||
| 62 | /* CP15 registers */ | 60 | /* CP15 registers */ |
| 63 | #define OPCODE_1 BITS(21, 23) | 61 | #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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2012 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | ||
| 5 | * as published by the Free Software Foundation; either version 2 | ||
| 6 | * of the License, or (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_interpreter.cpp | ||
| 20 | * @brief The fast interpreter for arm | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 7849 | ||
| 23 | * @date 2012-03-15 | ||
| 24 | */ | ||
| 25 | 4 | ||
| 26 | #define CITRA_IGNORE_EXIT(x) | 5 | #define CITRA_IGNORE_EXIT(x) |
| 27 | 6 | ||
| 28 | #include <algorithm> | 7 | #include <algorithm> |
| 29 | #include <map> | 8 | #include <unordered_map> |
| 30 | #include <stdio.h> | 9 | #include <stdio.h> |
| 31 | #include <assert.h> | 10 | #include <assert.h> |
| 32 | #include <cstdio> | 11 | #include <cstdio> |
| @@ -47,10 +26,6 @@ using namespace std; | |||
| 47 | #include "arm_dyncom_thumb.h" | 26 | #include "arm_dyncom_thumb.h" |
| 48 | #include "arm_dyncom_run.h" | 27 | #include "arm_dyncom_run.h" |
| 49 | #include "core/arm/skyeye_common/vfp/vfp.h" | 28 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 50 | /* shenoubang 2012-6-14 */ | ||
| 51 | #ifdef __WIN32__ | ||
| 52 | #include "bank_defs.h" | ||
| 53 | #endif | ||
| 54 | 29 | ||
| 55 | #include "core/mem_map.h" | 30 | #include "core/mem_map.h" |
| 56 | #include "core/hle/hle.h" | 31 | #include "core/hle/hle.h" |
| @@ -66,327 +41,243 @@ enum { | |||
| 66 | THUMB = (1 << 7) | 41 | THUMB = (1 << 7) |
| 67 | }; | 42 | }; |
| 68 | 43 | ||
| 69 | #define USER_MODE_OPT 1 | 44 | #define USER_MODE_OPT 1 |
| 70 | #define HYBRID_MODE 0 // Enable for JIT mode | 45 | #define HYBRID_MODE 0 // Enable for JIT mode |
| 71 | 46 | ||
| 72 | #define THRESHOLD 1000 | 47 | #define THRESHOLD 1000 |
| 73 | #define DURATION 500 | 48 | #define DURATION 500 |
| 74 | //#define PRINT_PROFILE_INFO | ||
| 75 | 49 | ||
| 76 | #define CHECK_RS if(RS == 15) rs += 8 | 50 | #define CHECK_RS if(RS == 15) rs += 8 |
| 77 | #define CHECK_RM if(RM == 15) rm += 8 | 51 | #define CHECK_RM if(RM == 15) rm += 8 |
| 78 | 52 | ||
| 79 | //#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1)) | ||
| 80 | #undef BITS | 53 | #undef BITS |
| 81 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) | 54 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) |
| 82 | #define BIT(s, n) ((s >> (n)) & 1) | 55 | #define BIT(s, n) ((s >> (n)) & 1) |
| 83 | #define RM BITS(sht_oper, 0, 3) | 56 | #define RM BITS(sht_oper, 0, 3) |
| 84 | #define RS BITS(sht_oper, 8, 11) | 57 | #define RS BITS(sht_oper, 8, 11) |
| 85 | 58 | ||
| 86 | #define glue(x, y) x ## y | 59 | #define glue(x, y) x ## y |
| 87 | #define DPO(s) glue(DataProcessingOperands, s) | 60 | #define DPO(s) glue(DataProcessingOperands, s) |
| 88 | #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) | 61 | #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) |
| 89 | #define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) | 62 | #define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) |
| 90 | #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) | 63 | #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) |
| 91 | #define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) | 64 | #define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) |
| 92 | 65 | ||
| 93 | //#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n)))) | ||
| 94 | //#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1))) | ||
| 95 | #define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) | 66 | #define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) |
| 96 | 67 | ||
| 97 | extern void switch_mode(arm_core_t *core, uint32_t mode); | 68 | extern void switch_mode(arm_core_t *core, uint32_t mode); |
| 98 | //extern bool InAPrivilegedMode(arm_core_t *core); | ||
| 99 | 69 | ||
| 100 | typedef arm_core_t arm_processor; | 70 | typedef arm_core_t arm_processor; |
| 101 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); | 71 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); |
| 102 | 72 | ||
| 103 | /* exclusive memory access */ | 73 | // Exclusive memory access |
| 104 | static int exclusive_detect(ARMul_State* state, ARMword addr){ | 74 | static int exclusive_detect(ARMul_State* state, ARMword addr){ |
| 105 | int i; | 75 | if(state->exclusive_tag == addr) |
| 106 | #if 0 | 76 | return 0; |
| 107 | for(i = 0; i < 128; i++){ | 77 | else |
| 108 | if(state->exclusive_tag_array[i] == addr) | 78 | return -1; |
| 109 | return 0; | ||
| 110 | } | ||
| 111 | #endif | ||
| 112 | if(state->exclusive_tag == addr) | ||
| 113 | return 0; | ||
| 114 | else | ||
| 115 | return -1; | ||
| 116 | } | 79 | } |
| 117 | 80 | ||
| 118 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ | 81 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ |
| 119 | int i; | 82 | state->exclusive_tag = addr; |
| 120 | #if 0 | 83 | return; |
| 121 | for(i = 0; i < 128; i++){ | ||
| 122 | if(state->exclusive_tag_array[i] == 0xffffffff){ | ||
| 123 | state->exclusive_tag_array[i] = addr; | ||
| 124 | //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr); | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__); | ||
| 129 | #endif | ||
| 130 | state->exclusive_tag = addr; | ||
| 131 | return; | ||
| 132 | } | 84 | } |
| 133 | 85 | ||
| 134 | static void remove_exclusive(ARMul_State* state, ARMword addr){ | 86 | static void remove_exclusive(ARMul_State* state, ARMword addr){ |
| 135 | #if 0 | 87 | state->exclusive_tag = 0xFFFFFFFF; |
| 136 | int i; | 88 | } |
| 137 | for(i = 0; i < 128; i++){ | 89 | |
| 138 | if(state->exclusive_tag_array[i] == addr){ | 90 | |
| 139 | state->exclusive_tag_array[i] = 0xffffffff; | 91 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { |
| 140 | //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr); | 92 | unsigned int immed_8 = BITS(sht_oper, 0, 7); |
| 141 | return; | 93 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); |
| 142 | } | 94 | unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2); |
| 143 | } | 95 | if (rotate_imm == 0) |
| 144 | #endif | 96 | cpu->shifter_carry_out = cpu->CFlag; |
| 145 | state->exclusive_tag = 0xFFFFFFFF; | 97 | else |
| 146 | } | 98 | cpu->shifter_carry_out = BIT(shifter_operand, 31); |
| 147 | 99 | return shifter_operand; | |
| 148 | 100 | } | |
| 149 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) | 101 | |
| 150 | { | 102 | unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) { |
| 151 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | 103 | unsigned int rm = CHECK_READ_REG15(cpu, RM); |
| 152 | unsigned int immed_8 = BITS(sht_oper, 0, 7); | 104 | unsigned int shifter_operand = rm; |
| 153 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); | 105 | cpu->shifter_carry_out = cpu->CFlag; |
| 154 | // DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8); | 106 | return shifter_operand; |
| 155 | // DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm); | 107 | } |
| 156 | unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2); | 108 | |
| 157 | // DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand); | 109 | unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) { |
| 158 | /* set c flag */ | 110 | int shift_imm = BITS(sht_oper, 7, 11); |
| 159 | if (rotate_imm == 0) | 111 | unsigned int rm = CHECK_READ_REG15(cpu, RM); |
| 160 | cpu->shifter_carry_out = cpu->CFlag; | 112 | unsigned int shifter_operand; |
| 161 | else | 113 | if (shift_imm == 0) { |
| 162 | cpu->shifter_carry_out = BIT(shifter_operand, 31); | 114 | shifter_operand = rm; |
| 163 | return shifter_operand; | 115 | cpu->shifter_carry_out = cpu->CFlag; |
| 164 | } | 116 | } else { |
| 165 | 117 | shifter_operand = rm << shift_imm; | |
| 166 | unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper) | 118 | cpu->shifter_carry_out = BIT(rm, 32 - shift_imm); |
| 167 | { | 119 | } |
| 168 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | 120 | return shifter_operand; |
| 169 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | 121 | } |
| 170 | //if (RM == 15) rm += 8; | 122 | |
| 171 | unsigned int shifter_operand = rm; | 123 | unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) { |
| 172 | cpu->shifter_carry_out = cpu->CFlag; | 124 | int shifter_operand; |
| 173 | return shifter_operand; | 125 | unsigned int rm = CHECK_READ_REG15(cpu, RM); |
| 126 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 127 | if (BITS(rs, 0, 7) == 0) { | ||
| 128 | shifter_operand = rm; | ||
| 129 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 130 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 131 | shifter_operand = rm << BITS(rs, 0, 7); | ||
| 132 | cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7)); | ||
| 133 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 134 | shifter_operand = 0; | ||
| 135 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 136 | } else { | ||
| 137 | shifter_operand = 0; | ||
| 138 | cpu->shifter_carry_out = 0; | ||
| 139 | } | ||
| 140 | return shifter_operand; | ||
| 141 | } | ||
| 142 | |||
| 143 | unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 144 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 145 | unsigned int shifter_operand; | ||
| 146 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 147 | if (shift_imm == 0) { | ||
| 148 | shifter_operand = 0; | ||
| 149 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 150 | } else { | ||
| 151 | shifter_operand = rm >> shift_imm; | ||
| 152 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 153 | } | ||
| 154 | return shifter_operand; | ||
| 155 | } | ||
| 156 | |||
| 157 | unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 158 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 159 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 160 | unsigned int shifter_operand; | ||
| 161 | if (BITS(rs, 0, 7) == 0) { | ||
| 162 | shifter_operand = rm; | ||
| 163 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 164 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 165 | shifter_operand = rm >> BITS(rs, 0, 7); | ||
| 166 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 167 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 168 | shifter_operand = 0; | ||
| 169 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 170 | } else { | ||
| 171 | shifter_operand = 0; | ||
| 172 | cpu->shifter_carry_out = 0; | ||
| 173 | } | ||
| 174 | return shifter_operand; | ||
| 175 | } | ||
| 176 | |||
| 177 | unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 178 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 179 | unsigned int shifter_operand; | ||
| 180 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 181 | if (shift_imm == 0) { | ||
| 182 | if (BIT(rm, 31)) { | ||
| 183 | shifter_operand = 0; | ||
| 184 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 185 | } else { | ||
| 186 | shifter_operand = 0xFFFFFFFF; | ||
| 187 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 188 | } | ||
| 189 | } else { | ||
| 190 | shifter_operand = static_cast<int>(rm) >> shift_imm; | ||
| 191 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 192 | } | ||
| 193 | return shifter_operand; | ||
| 194 | } | ||
| 195 | |||
| 196 | unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 197 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 198 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 199 | unsigned int shifter_operand; | ||
| 200 | if (BITS(rs, 0, 7) == 0) { | ||
| 201 | shifter_operand = rm; | ||
| 202 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 203 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 204 | shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7); | ||
| 205 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 206 | } else { | ||
| 207 | if (BIT(rm, 31) == 0) | ||
| 208 | shifter_operand = 0; | ||
| 209 | else | ||
| 210 | shifter_operand = 0xffffffff; | ||
| 211 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 212 | } | ||
| 213 | return shifter_operand; | ||
| 214 | } | ||
| 215 | |||
| 216 | unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 217 | unsigned int shifter_operand; | ||
| 218 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 219 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 220 | if (shift_imm == 0) { | ||
| 221 | shifter_operand = (cpu->CFlag << 31) | (rm >> 1); | ||
| 222 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 223 | } else { | ||
| 224 | shifter_operand = ROTATE_RIGHT_32(rm, shift_imm); | ||
| 225 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 226 | } | ||
| 227 | return shifter_operand; | ||
| 228 | } | ||
| 229 | |||
| 230 | unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) { | ||
| 231 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 232 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 233 | unsigned int shifter_operand; | ||
| 234 | if (BITS(rs, 0, 7) == 0) { | ||
| 235 | shifter_operand = rm; | ||
| 236 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 237 | } else if (BITS(rs, 0, 4) == 0) { | ||
| 238 | shifter_operand = rm; | ||
| 239 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 240 | } else { | ||
| 241 | shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4)); | ||
| 242 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1); | ||
| 243 | } | ||
| 244 | return shifter_operand; | ||
| 174 | } | 245 | } |
| 175 | 246 | ||
| 176 | unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 177 | { | ||
| 178 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 179 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 180 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 181 | //if (RM == 15) rm += 8; | ||
| 182 | unsigned int shifter_operand; | ||
| 183 | if (shift_imm == 0) { | ||
| 184 | shifter_operand = rm; | ||
| 185 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 186 | } else { | ||
| 187 | shifter_operand = rm << shift_imm; | ||
| 188 | cpu->shifter_carry_out = BIT(rm, 32 - shift_imm); | ||
| 189 | } | ||
| 190 | return shifter_operand; | ||
| 191 | } | ||
| 192 | |||
| 193 | unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 194 | { | ||
| 195 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 196 | int shifter_operand; | ||
| 197 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 198 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 199 | //if (RM == 15) rm += 8; | ||
| 200 | //if (RS == 15) rs += 8; | ||
| 201 | if (BITS(rs, 0, 7) == 0) { | ||
| 202 | shifter_operand = rm; | ||
| 203 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 204 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 205 | shifter_operand = rm << BITS(rs, 0, 7); | ||
| 206 | cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7)); | ||
| 207 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 208 | shifter_operand = 0; | ||
| 209 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 210 | } else { | ||
| 211 | shifter_operand = 0; | ||
| 212 | cpu->shifter_carry_out = 0; | ||
| 213 | } | ||
| 214 | return shifter_operand; | ||
| 215 | } | ||
| 216 | |||
| 217 | unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 218 | { | ||
| 219 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 220 | //unsigned int rm = cpu->Reg[RM]; | ||
| 221 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 222 | //if (RM == 15) rm += 8; | ||
| 223 | unsigned int shifter_operand; | ||
| 224 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 225 | if (shift_imm == 0) { | ||
| 226 | shifter_operand = 0; | ||
| 227 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 228 | } else { | ||
| 229 | shifter_operand = rm >> shift_imm; | ||
| 230 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 231 | } | ||
| 232 | return shifter_operand; | ||
| 233 | } | ||
| 234 | |||
| 235 | unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 236 | { | ||
| 237 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 238 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 239 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 240 | //if (RS == 15) rs += 8; | ||
| 241 | //if (RM == 15) rm += 8; | ||
| 242 | unsigned int shifter_operand; | ||
| 243 | if (BITS(rs, 0, 7) == 0) { | ||
| 244 | shifter_operand = rm; | ||
| 245 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 246 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 247 | shifter_operand = rm >> BITS(rs, 0, 7); | ||
| 248 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 249 | } else if (BITS(rs, 0, 7) == 32) { | ||
| 250 | shifter_operand = 0; | ||
| 251 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 252 | } else { | ||
| 253 | shifter_operand = 0; | ||
| 254 | cpu->shifter_carry_out = 0; | ||
| 255 | } | ||
| 256 | return shifter_operand; | ||
| 257 | } | ||
| 258 | |||
| 259 | unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 260 | { | ||
| 261 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 262 | //unsigned int rm = cpu->Reg[RM]; | ||
| 263 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 264 | //if (RM == 15) rm += 8; | ||
| 265 | unsigned int shifter_operand; | ||
| 266 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 267 | if (shift_imm == 0) { | ||
| 268 | if (BIT(rm, 31)) { | ||
| 269 | shifter_operand = 0; | ||
| 270 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 271 | } else { | ||
| 272 | shifter_operand = 0xFFFFFFFF; | ||
| 273 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 274 | } | ||
| 275 | } else { | ||
| 276 | shifter_operand = static_cast<int>(rm) >> shift_imm; | ||
| 277 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 278 | } | ||
| 279 | return shifter_operand; | ||
| 280 | } | ||
| 281 | |||
| 282 | unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 283 | { | ||
| 284 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 285 | //unsigned int rs = cpu->Reg[RS]; | ||
| 286 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 287 | //unsigned int rm = cpu->Reg[RM]; | ||
| 288 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 289 | //if (RS == 15) rs += 8; | ||
| 290 | //if (RM == 15) rm += 8; | ||
| 291 | unsigned int shifter_operand; | ||
| 292 | if (BITS(rs, 0, 7) == 0) { | ||
| 293 | shifter_operand = rm; | ||
| 294 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 295 | } else if (BITS(rs, 0, 7) < 32) { | ||
| 296 | shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7); | ||
| 297 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1); | ||
| 298 | } else { | ||
| 299 | if (BIT(rm, 31) == 0) { | ||
| 300 | shifter_operand = 0; | ||
| 301 | } else | ||
| 302 | shifter_operand = 0xffffffff; | ||
| 303 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 304 | } | ||
| 305 | return shifter_operand; | ||
| 306 | } | ||
| 307 | |||
| 308 | unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper) | ||
| 309 | { | ||
| 310 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 311 | unsigned int shifter_operand; | ||
| 312 | //unsigned int rm = cpu->Reg[RM]; | ||
| 313 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 314 | //if (RM == 15) rm += 8; | ||
| 315 | int shift_imm = BITS(sht_oper, 7, 11); | ||
| 316 | if (shift_imm == 0) { | ||
| 317 | shifter_operand = (cpu->CFlag << 31) | | ||
| 318 | (rm >> 1); | ||
| 319 | cpu->shifter_carry_out = BIT(rm, 0); | ||
| 320 | } else { | ||
| 321 | shifter_operand = ROTATE_RIGHT_32(rm, shift_imm); | ||
| 322 | cpu->shifter_carry_out = BIT(rm, shift_imm - 1); | ||
| 323 | } | ||
| 324 | return shifter_operand; | ||
| 325 | } | ||
| 326 | |||
| 327 | unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper) | ||
| 328 | { | ||
| 329 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 330 | unsigned int rm = CHECK_READ_REG15(cpu, RM); | ||
| 331 | //if (RM == 15) rm += 8; | ||
| 332 | unsigned int rs = CHECK_READ_REG15(cpu, RS); | ||
| 333 | //if (RS == 15) rs += 8; | ||
| 334 | unsigned int shifter_operand; | ||
| 335 | if (BITS(rs, 0, 7) == 0) { | ||
| 336 | shifter_operand = rm; | ||
| 337 | cpu->shifter_carry_out = cpu->CFlag; | ||
| 338 | } else if (BITS(rs, 0, 4) == 0) { | ||
| 339 | shifter_operand = rm; | ||
| 340 | cpu->shifter_carry_out = BIT(rm, 31); | ||
| 341 | } else { | ||
| 342 | shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4)); | ||
| 343 | cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1); | ||
| 344 | } | ||
| 345 | #if 0 | ||
| 346 | if (cpu->icounter >= 20371544) { | ||
| 347 | DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | ||
| 348 | DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS); | ||
| 349 | DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]); | ||
| 350 | } | ||
| 351 | #endif | ||
| 352 | return shifter_operand; | ||
| 353 | } | ||
| 354 | |||
| 355 | //typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu); | ||
| 356 | typedef struct _MiscImmeData { | 247 | typedef struct _MiscImmeData { |
| 357 | unsigned int U; | 248 | unsigned int U; |
| 358 | unsigned int Rn; | 249 | unsigned int Rn; |
| 359 | unsigned int offset_8; | 250 | unsigned int offset_8; |
| 360 | } MiscLSData; | 251 | } MiscLSData; |
| 361 | 252 | ||
| 362 | typedef struct _MiscRegData { | 253 | typedef struct _MiscRegData { |
| 363 | unsigned int U; | 254 | unsigned int U; |
| 364 | unsigned int Rn; | 255 | unsigned int Rn; |
| 365 | unsigned int Rm; | 256 | unsigned int Rm; |
| 366 | } MiscRegData; | 257 | } MiscRegData; |
| 367 | 258 | ||
| 368 | typedef struct _MiscImmePreIdx { | 259 | typedef struct _MiscImmePreIdx { |
| 369 | unsigned int offset_8; | 260 | unsigned int offset_8; |
| 370 | unsigned int U; | 261 | unsigned int U; |
| 371 | unsigned int Rn; | 262 | unsigned int Rn; |
| 372 | } MiscImmePreIdx; | 263 | } MiscImmePreIdx; |
| 373 | 264 | ||
| 374 | typedef struct _MiscRegPreIdx { | 265 | typedef struct _MiscRegPreIdx { |
| 375 | unsigned int U; | 266 | unsigned int U; |
| 376 | unsigned int Rn; | 267 | unsigned int Rn; |
| 377 | unsigned int Rm; | 268 | unsigned int Rm; |
| 378 | } MiscRegPreIdx; | 269 | } MiscRegPreIdx; |
| 379 | 270 | ||
| 380 | typedef struct _MiscImmePstIdx { | 271 | typedef struct _MiscImmePstIdx { |
| 381 | unsigned int offset_8; | 272 | unsigned int offset_8; |
| 382 | unsigned int U; | 273 | unsigned int U; |
| 383 | unsigned int Rn; | 274 | unsigned int Rn; |
| 384 | } MIscImmePstIdx; | 275 | } MIscImmePstIdx; |
| 385 | 276 | ||
| 386 | typedef struct _MiscRegPstIdx { | 277 | typedef struct _MiscRegPstIdx { |
| 387 | unsigned int Rn; | 278 | unsigned int Rn; |
| 388 | unsigned int Rm; | 279 | unsigned int Rm; |
| 389 | unsigned int U; | 280 | unsigned int U; |
| 390 | } MiscRegPstIdx; | 281 | } MiscRegPstIdx; |
| 391 | 282 | ||
| 392 | typedef struct _LSWordorUnsignedByte { | 283 | typedef struct _LSWordorUnsignedByte { |
| @@ -394,40 +285,38 @@ typedef struct _LSWordorUnsignedByte { | |||
| 394 | 285 | ||
| 395 | #if USER_MODE_OPT | 286 | #if USER_MODE_OPT |
| 396 | static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ | 287 | static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ |
| 397 | switch(size) { | 288 | switch(size) { |
| 398 | case 8: | 289 | case 8: |
| 399 | value = Memory::Read8(virt_addr); | 290 | value = Memory::Read8(virt_addr); |
| 400 | break; | 291 | break; |
| 401 | case 16: | 292 | case 16: |
| 402 | value = Memory::Read16(virt_addr); | 293 | value = Memory::Read16(virt_addr); |
| 403 | break; | 294 | break; |
| 404 | case 32: | 295 | case 32: |
| 405 | value = Memory::Read32(virt_addr); | 296 | value = Memory::Read32(virt_addr); |
| 406 | break; | 297 | break; |
| 407 | } | 298 | } |
| 408 | return NO_FAULT; | 299 | return NO_FAULT; |
| 409 | } | 300 | } |
| 410 | 301 | ||
| 411 | //static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size) | 302 | static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) { |
| 412 | static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) | 303 | switch(size) { |
| 413 | { | 304 | case 8: |
| 414 | switch(size) { | ||
| 415 | case 8: | ||
| 416 | Memory::Write8(virt_addr, value & 0xff); | 305 | Memory::Write8(virt_addr, value & 0xff); |
| 417 | break; | 306 | break; |
| 418 | case 16: | 307 | case 16: |
| 419 | Memory::Write16(virt_addr, value & 0xffff); | 308 | Memory::Write16(virt_addr, value & 0xffff); |
| 420 | break; | 309 | break; |
| 421 | case 32: | 310 | case 32: |
| 422 | Memory::Write32(virt_addr, value); | 311 | Memory::Write32(virt_addr, value); |
| 423 | break; | 312 | break; |
| 424 | } | 313 | } |
| 425 | return NO_FAULT; | 314 | return NO_FAULT; |
| 426 | } | 315 | } |
| 427 | 316 | ||
| 428 | static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){ | 317 | static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw) { |
| 429 | *phys_addr = virt_addr; | 318 | *phys_addr = virt_addr; |
| 430 | return NO_FAULT; | 319 | return NO_FAULT; |
| 431 | } | 320 | } |
| 432 | 321 | ||
| 433 | #else | 322 | #else |
| @@ -440,738 +329,679 @@ fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_ | |||
| 440 | typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); | 329 | typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); |
| 441 | 330 | ||
| 442 | typedef struct _ldst_inst { | 331 | typedef struct _ldst_inst { |
| 443 | unsigned int inst; | 332 | unsigned int inst; |
| 444 | get_addr_fp_t get_addr; | 333 | get_addr_fp_t get_addr; |
| 445 | } ldst_inst; | 334 | } ldst_inst; |
| 446 | #define DEBUG_MSG DEBUG_LOG(ARM11, "in %s %d\n", __FUNCTION__, __LINE__); \ | 335 | #define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0) |
| 447 | DEBUG_LOG(ARM11, "inst is %x\n", inst); \ | ||
| 448 | CITRA_IGNORE_EXIT(0) | ||
| 449 | 336 | ||
| 450 | int CondPassed(arm_processor *cpu, unsigned int cond); | 337 | int CondPassed(arm_processor *cpu, unsigned int cond); |
| 451 | #define LnSWoUB(s) glue(LnSWoUB, s) | 338 | #define LnSWoUB(s) glue(LnSWoUB, s) |
| 452 | #define MLnS(s) glue(MLnS, s) | 339 | #define MLnS(s) glue(MLnS, s) |
| 453 | #define LdnStM(s) glue(LdnStM, s) | 340 | #define LdnStM(s) glue(LdnStM, s) |
| 454 | 341 | ||
| 455 | #define W_BIT BIT(inst, 21) | 342 | #define W_BIT BIT(inst, 21) |
| 456 | #define U_BIT BIT(inst, 23) | 343 | #define U_BIT BIT(inst, 23) |
| 457 | #define I_BIT BIT(inst, 25) | 344 | #define I_BIT BIT(inst, 25) |
| 458 | #define P_BIT BIT(inst, 24) | 345 | #define P_BIT BIT(inst, 24) |
| 459 | #define OFFSET_12 BITS(inst, 0, 11) | 346 | #define OFFSET_12 BITS(inst, 0, 11) |
| 460 | fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 347 | fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 461 | { | 348 | unsigned int Rn = BITS(inst, 16, 19); |
| 462 | unsigned int Rn = BITS(inst, 16, 19); | 349 | unsigned int addr; |
| 463 | unsigned int addr; | 350 | fault_t fault; |
| 464 | fault_t fault; | 351 | if (U_BIT) { |
| 465 | if (U_BIT) { | 352 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; |
| 466 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | 353 | } else { |
| 467 | } else { | 354 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; |
| 468 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | 355 | } |
| 469 | } | 356 | virt_addr = addr; |
| 470 | //if (Rn == 15) rn += 8; | 357 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 471 | virt_addr = addr; | 358 | return fault; |
| 472 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 359 | } |
| 473 | return fault; | 360 | |
| 474 | // return addr; | 361 | fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 475 | } | 362 | fault_t fault; |
| 476 | 363 | unsigned int Rn = BITS(inst, 16, 19); | |
| 477 | fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 364 | unsigned int Rm = BITS(inst, 0, 3); |
| 478 | { | 365 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 479 | fault_t fault; | 366 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 480 | unsigned int Rn = BITS(inst, 16, 19); | 367 | unsigned int addr; |
| 481 | unsigned int Rm = BITS(inst, 0, 3); | 368 | if (U_BIT) { |
| 482 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 369 | addr = rn + rm; |
| 483 | //if (Rn == 15) rn += 8; | 370 | } else { |
| 484 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 371 | addr = rn - rm; |
| 485 | //if (Rm == 15) rm += 8; | 372 | } |
| 486 | unsigned int addr; | 373 | virt_addr = addr; |
| 487 | if (U_BIT) { | 374 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 488 | addr = rn + rm; | 375 | return fault; |
| 489 | } else { | 376 | } |
| 490 | addr = rn - rm; | 377 | |
| 491 | } | 378 | fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 492 | virt_addr = addr; | 379 | fault_t fault; |
| 493 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 380 | unsigned int Rn = BITS(inst, 16, 19); |
| 494 | return fault; | 381 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 495 | } | 382 | |
| 496 | 383 | virt_addr = addr; | |
| 497 | fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 384 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 498 | { | 385 | if (fault) return fault; |
| 499 | fault_t fault; | 386 | |
| 500 | unsigned int Rn = BITS(inst, 16, 19); | 387 | if (U_BIT) { |
| 501 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); | 388 | cpu->Reg[Rn] += OFFSET_12; |
| 502 | //if (Rn == 15) addr += 8; | 389 | } else { |
| 390 | cpu->Reg[Rn] -= OFFSET_12; | ||
| 391 | } | ||
| 392 | return fault; | ||
| 393 | } | ||
| 503 | 394 | ||
| 504 | virt_addr = addr; | 395 | fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 505 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 396 | fault_t fault; |
| 506 | if (fault) return fault; | 397 | unsigned int Rn = BITS(inst, 16, 19); |
| 398 | unsigned int addr; | ||
| 399 | if (U_BIT) { | ||
| 400 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | ||
| 401 | } else { | ||
| 402 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | ||
| 403 | } | ||
| 404 | |||
| 405 | virt_addr = addr; | ||
| 406 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 407 | if (fault) return fault; | ||
| 507 | 408 | ||
| 508 | if (U_BIT) { | 409 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 509 | cpu->Reg[Rn] += OFFSET_12; | 410 | cpu->Reg[Rn] = addr; |
| 510 | } else { | 411 | } |
| 511 | cpu->Reg[Rn] -= OFFSET_12; | 412 | return fault; |
| 512 | } | 413 | } |
| 513 | return fault; | 414 | |
| 415 | fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 416 | fault_t fault; | ||
| 417 | unsigned int addr; | ||
| 418 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 419 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 420 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 421 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 422 | |||
| 423 | if (U_BIT) { | ||
| 424 | addr = rn + rm; | ||
| 425 | } else | ||
| 426 | addr = rn - rm; | ||
| 427 | if(BIT(inst, 20)){ // L BIT | ||
| 428 | } | ||
| 429 | if(BIT(inst, 6)){ // Sign Bit | ||
| 430 | } | ||
| 431 | if(BIT(inst, 5)){ // Half Bit | ||
| 432 | } | ||
| 433 | |||
| 434 | virt_addr = addr; | ||
| 435 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 436 | if (fault) return fault; | ||
| 437 | |||
| 438 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 439 | cpu->Reg[Rn] = addr; | ||
| 440 | } | ||
| 441 | return fault; | ||
| 442 | } | ||
| 443 | |||
| 444 | fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 445 | fault_t fault; | ||
| 446 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 447 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 448 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 449 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 450 | unsigned int addr; | ||
| 451 | if (U_BIT) { | ||
| 452 | addr = rn + rm; | ||
| 453 | } else { | ||
| 454 | addr = rn - rm; | ||
| 455 | } | ||
| 456 | virt_addr = addr; | ||
| 457 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 458 | if(fault) | ||
| 459 | return fault; | ||
| 460 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 461 | cpu->Reg[Rn] = addr; | ||
| 462 | } | ||
| 463 | return fault; | ||
| 464 | } | ||
| 465 | fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 466 | fault_t fault; | ||
| 467 | unsigned int shift = BITS(inst, 5, 6); | ||
| 468 | unsigned int shift_imm = BITS(inst, 7, 11); | ||
| 469 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 470 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 471 | unsigned int index; | ||
| 472 | unsigned int addr; | ||
| 473 | |||
| 474 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 475 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 476 | |||
| 477 | switch (shift) { | ||
| 478 | case 0: | ||
| 479 | index = rm << shift_imm; | ||
| 480 | break; | ||
| 481 | case 1: | ||
| 482 | if (shift_imm == 0) { | ||
| 483 | index = 0; | ||
| 484 | } else { | ||
| 485 | index = rm >> shift_imm; | ||
| 486 | } | ||
| 487 | break; | ||
| 488 | case 2: | ||
| 489 | DEBUG_MSG; | ||
| 490 | break; | ||
| 491 | case 3: | ||
| 492 | DEBUG_MSG; | ||
| 493 | break; | ||
| 494 | } | ||
| 495 | if (U_BIT) { | ||
| 496 | addr = rn + index; | ||
| 497 | } else | ||
| 498 | addr = rn - index; | ||
| 499 | virt_addr = addr; | ||
| 500 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 501 | if(fault) | ||
| 502 | return fault; | ||
| 503 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 504 | cpu->Reg[Rn] = addr; | ||
| 505 | } | ||
| 506 | |||
| 507 | return fault; | ||
| 508 | } | ||
| 509 | |||
| 510 | fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | ||
| 511 | fault_t fault; | ||
| 512 | unsigned int shift = BITS(inst, 5, 6); | ||
| 513 | unsigned int shift_imm = BITS(inst, 7, 11); | ||
| 514 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 515 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 516 | unsigned int index; | ||
| 517 | unsigned int addr; | ||
| 518 | |||
| 519 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 520 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 521 | addr = rn; | ||
| 522 | switch (shift) { | ||
| 523 | case 0: | ||
| 524 | index = rm << shift_imm; | ||
| 525 | break; | ||
| 526 | case 1: | ||
| 527 | if (shift_imm == 0) { | ||
| 528 | index = 0; | ||
| 529 | } else { | ||
| 530 | index = rm >> shift_imm; | ||
| 531 | } | ||
| 532 | break; | ||
| 533 | case 2: | ||
| 534 | DEBUG_MSG; | ||
| 535 | break; | ||
| 536 | case 3: | ||
| 537 | DEBUG_MSG; | ||
| 538 | break; | ||
| 539 | } | ||
| 540 | virt_addr = addr; | ||
| 541 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 542 | if(fault) | ||
| 543 | return fault; | ||
| 544 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 545 | if (U_BIT) | ||
| 546 | cpu->Reg[Rn] += index; | ||
| 547 | else | ||
| 548 | cpu->Reg[Rn] -= index; | ||
| 549 | } | ||
| 550 | |||
| 551 | return fault; | ||
| 514 | } | 552 | } |
| 515 | 553 | ||
| 516 | fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 554 | fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 517 | { | 555 | fault_t fault; |
| 518 | fault_t fault; | 556 | unsigned int Rn = BITS(inst, 16, 19); |
| 519 | unsigned int Rn = BITS(inst, 16, 19); | 557 | unsigned int Rm = BITS(inst, 0, 3); |
| 520 | unsigned int addr; | 558 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 521 | if (U_BIT) { | 559 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 522 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | 560 | |
| 523 | } else { | 561 | unsigned int addr = rn; |
| 524 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | 562 | virt_addr = addr; |
| 525 | } | 563 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 526 | #if 0 | 564 | if (fault) return fault; |
| 527 | if (Rn == 15) { | 565 | |
| 528 | addr += 8; | 566 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 529 | } | 567 | if (U_BIT) { |
| 530 | #endif | 568 | cpu->Reg[Rn] += rm; |
| 531 | 569 | } else { | |
| 532 | virt_addr = addr; | 570 | cpu->Reg[Rn] -= rm; |
| 533 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 571 | } |
| 534 | if (fault) return fault; | 572 | } |
| 535 | 573 | return fault; | |
| 536 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 574 | } |
| 537 | cpu->Reg[Rn] = addr; | 575 | |
| 538 | } | 576 | fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 539 | return fault; | 577 | fault_t fault; |
| 540 | } | 578 | unsigned int immedL = BITS(inst, 0, 3); |
| 541 | 579 | unsigned int immedH = BITS(inst, 8, 11); | |
| 542 | fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 580 | |
| 543 | { | 581 | unsigned int Rn = BITS(inst, 16, 19); |
| 544 | fault_t fault; | 582 | unsigned int addr; |
| 545 | unsigned int addr; | 583 | |
| 546 | unsigned int Rn = BITS(inst, 16, 19); | 584 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 547 | unsigned int Rm = BITS(inst, 0, 3); | 585 | if (U_BIT) { |
| 548 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 586 | addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; |
| 549 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 587 | } else |
| 550 | //if (Rn == 15) rn += 8; | 588 | addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; |
| 551 | //if (Rm == 15) rm += 8; | 589 | |
| 552 | if (U_BIT) { | 590 | virt_addr = addr; |
| 553 | addr = rn + rm; | 591 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 554 | } else | 592 | return fault; |
| 555 | addr = rn - rm; | 593 | } |
| 556 | if(BIT(inst, 20)){ /* L BIT */ | 594 | |
| 557 | } | 595 | fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 558 | if(BIT(inst, 6)){ /* Sign Bit */ | 596 | fault_t fault; |
| 559 | } | 597 | unsigned int addr; |
| 560 | if(BIT(inst, 5)){ /* Half Bit */ | 598 | unsigned int Rn = BITS(inst, 16, 19); |
| 561 | } | 599 | unsigned int Rm = BITS(inst, 0, 3); |
| 562 | 600 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | |
| 563 | virt_addr = addr; | 601 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 564 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 602 | if (U_BIT) { |
| 565 | if (fault) return fault; | 603 | addr = rn + rm; |
| 566 | 604 | } else | |
| 567 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 605 | addr = rn - rm; |
| 568 | cpu->Reg[Rn] = addr; | 606 | if(BIT(inst, 20)){ // L BIT |
| 569 | } | 607 | } |
| 570 | return fault; | 608 | if(BIT(inst, 6)){ // Sign Bit |
| 571 | } | 609 | } |
| 572 | 610 | if(BIT(inst, 5)){ // Half Bit | |
| 573 | fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 611 | } |
| 574 | { | 612 | virt_addr = addr; |
| 575 | fault_t fault; | 613 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 576 | unsigned int Rn = BITS(inst, 16, 19); | 614 | return fault; |
| 577 | unsigned int Rm = BITS(inst, 0, 3); | 615 | } |
| 578 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 616 | |
| 579 | //if (Rn == 15) rn += 8; | 617 | fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 580 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 618 | fault_t fault; |
| 581 | //if (Rm == 15) rm += 8; | 619 | unsigned int Rn = BITS(inst, 16, 19); |
| 582 | unsigned int addr; | 620 | unsigned int immedH = BITS(inst, 8, 11); |
| 583 | if (U_BIT) { | 621 | unsigned int immedL = BITS(inst, 0, 3); |
| 584 | addr = rn + rm; | 622 | unsigned int addr; |
| 585 | } else { | 623 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 586 | addr = rn - rm; | 624 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 587 | } | 625 | |
| 588 | virt_addr = addr; | 626 | if (U_BIT) { |
| 589 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 627 | addr = rn + offset_8; |
| 590 | if(fault) | 628 | } else |
| 591 | return fault; | 629 | addr = rn - offset_8; |
| 592 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 630 | |
| 593 | cpu->Reg[Rn] = addr; | 631 | virt_addr = addr; |
| 594 | } | 632 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 595 | return fault; | 633 | if (fault) return fault; |
| 596 | } | 634 | |
| 597 | fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 635 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 598 | { | 636 | cpu->Reg[Rn] = addr; |
| 599 | fault_t fault; | 637 | } |
| 600 | unsigned int shift = BITS(inst, 5, 6); | 638 | return fault; |
| 601 | unsigned int shift_imm = BITS(inst, 7, 11); | 639 | } |
| 602 | unsigned int Rn = BITS(inst, 16, 19); | 640 | |
| 603 | unsigned int Rm = BITS(inst, 0, 3); | 641 | fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 604 | unsigned int index; | 642 | fault_t fault; |
| 605 | unsigned int addr; | 643 | unsigned int Rn = BITS(inst, 16, 19); |
| 606 | 644 | unsigned int immedH = BITS(inst, 8, 11); | |
| 607 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 645 | unsigned int immedL = BITS(inst, 0, 3); |
| 608 | //if (Rm == 15) rm += 8; | 646 | unsigned int addr; |
| 609 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 647 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 610 | //if (Rn == 15) rn += 8; | 648 | addr = rn; |
| 611 | switch (shift) { | 649 | |
| 612 | case 0: | 650 | virt_addr = addr; |
| 613 | //DEBUG_MSG; | 651 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 614 | index = rm << shift_imm; | 652 | if (fault) return fault; |
| 615 | break; | 653 | |
| 616 | case 1: | 654 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 617 | // DEBUG_MSG; | 655 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 618 | if (shift_imm == 0) { | 656 | if (U_BIT) { |
| 619 | index = 0; | 657 | rn += offset_8; |
| 620 | } else { | 658 | } else { |
| 621 | index = rm >> shift_imm; | 659 | rn -= offset_8; |
| 622 | } | 660 | } |
| 623 | break; | 661 | cpu->Reg[Rn] = rn; |
| 624 | case 2: | 662 | } |
| 625 | DEBUG_MSG; | 663 | |
| 626 | break; | 664 | return fault; |
| 627 | case 3: | 665 | } |
| 628 | DEBUG_MSG; | 666 | fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 629 | break; | 667 | fault_t fault; |
| 630 | } | 668 | unsigned int Rn = BITS(inst, 16, 19); |
| 631 | if (U_BIT) { | 669 | unsigned int Rm = BITS(inst, 0, 3); |
| 632 | addr = rn + index; | 670 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 633 | } else | 671 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 634 | addr = rn - index; | 672 | unsigned int addr = rn; |
| 635 | virt_addr = addr; | 673 | |
| 636 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 674 | virt_addr = addr; |
| 637 | if(fault) | 675 | fault = check_address_validity(cpu, addr, &phys_addr, rw); |
| 638 | return fault; | 676 | if (fault) return fault; |
| 639 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 677 | |
| 640 | cpu->Reg[Rn] = addr; | 678 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 641 | } | 679 | if (U_BIT) { |
| 642 | 680 | cpu->Reg[Rn] += rm; | |
| 643 | return fault; | 681 | } else { |
| 644 | } | 682 | cpu->Reg[Rn] -= rm; |
| 645 | 683 | } | |
| 646 | fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 684 | } |
| 647 | { | 685 | return fault; |
| 648 | fault_t fault; | 686 | } |
| 649 | unsigned int shift = BITS(inst, 5, 6); | 687 | |
| 650 | unsigned int shift_imm = BITS(inst, 7, 11); | 688 | fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 651 | unsigned int Rn = BITS(inst, 16, 19); | 689 | fault_t fault; |
| 652 | unsigned int Rm = BITS(inst, 0, 3); | 690 | unsigned int Rn = BITS(inst, 16, 19); |
| 653 | unsigned int index; | 691 | unsigned int i = BITS(inst, 0, 15); |
| 654 | unsigned int addr; | 692 | int count = 0; |
| 655 | 693 | while(i) { | |
| 656 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 694 | if(i & 1) count ++; |
| 657 | //if (Rm == 15) rm += 8; | 695 | i = i >> 1; |
| 658 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 696 | } |
| 659 | //if (Rn == 15) rn += 8; | 697 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 660 | addr = rn; | 698 | unsigned int start_addr = rn - count * 4; |
| 661 | switch (shift) { | 699 | unsigned int end_addr = rn - 4; |
| 662 | case 0: | 700 | |
| 663 | //DEBUG_MSG; | 701 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 664 | index = rm << shift_imm; | 702 | virt_addr = end_addr; |
| 665 | break; | 703 | if (fault) return fault; |
| 666 | case 1: | 704 | |
| 667 | // DEBUG_MSG; | 705 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); |
| 668 | if (shift_imm == 0) { | 706 | virt_addr = start_addr; |
| 669 | index = 0; | 707 | if (fault) return fault; |
| 670 | } else { | 708 | |
| 671 | index = rm >> shift_imm; | 709 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 672 | } | 710 | cpu->Reg[Rn] -= count * 4; |
| 673 | break; | 711 | } |
| 674 | case 2: | 712 | |
| 675 | DEBUG_MSG; | 713 | return fault; |
| 676 | break; | 714 | } |
| 677 | case 3: | 715 | |
| 678 | DEBUG_MSG; | 716 | fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 679 | break; | 717 | fault_t fault; |
| 680 | } | 718 | unsigned int Rn = BITS(inst, 16, 19); |
| 681 | virt_addr = addr; | 719 | unsigned int i = BITS(inst, 0, 15); |
| 682 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 720 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 683 | if(fault) | 721 | int count = 0; |
| 684 | return fault; | 722 | while(i) { |
| 685 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 723 | if(i & 1) count ++; |
| 686 | if (U_BIT) | 724 | i = i >> 1; |
| 687 | cpu->Reg[Rn] += index; | 725 | } |
| 688 | else | 726 | |
| 689 | cpu->Reg[Rn] -= index; | 727 | unsigned int start_addr = rn + 4; |
| 690 | } | 728 | unsigned int end_addr = rn + count * 4; |
| 691 | 729 | ||
| 692 | return fault; | 730 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 693 | } | 731 | virt_addr = end_addr; |
| 694 | 732 | if (fault) return fault; | |
| 695 | fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 733 | |
| 696 | { | 734 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); |
| 697 | fault_t fault; | 735 | virt_addr = start_addr; |
| 698 | unsigned int Rn = BITS(inst, 16, 19); | 736 | if (fault) return fault; |
| 699 | unsigned int Rm = BITS(inst, 0, 3); | 737 | |
| 700 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 738 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 701 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 739 | cpu->Reg[Rn] += count * 4; |
| 702 | 740 | } | |
| 703 | unsigned int addr = rn; | 741 | return fault; |
| 704 | virt_addr = addr; | 742 | } |
| 705 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 743 | |
| 706 | if (fault) return fault; | 744 | fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 707 | 745 | fault_t fault; | |
| 708 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 746 | unsigned int Rn = BITS(inst, 16, 19); |
| 709 | if (U_BIT) { | 747 | unsigned int i = BITS(inst, 0, 15); |
| 710 | cpu->Reg[Rn] += rm; | 748 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 711 | } else { | 749 | int count = 0; |
| 712 | cpu->Reg[Rn] -= rm; | 750 | while(i) { |
| 713 | } | 751 | if(i & 1) count ++; |
| 714 | } | 752 | i = i >> 1; |
| 715 | return fault; | 753 | } |
| 716 | } | 754 | unsigned int start_addr = rn; |
| 717 | 755 | unsigned int end_addr = rn + count * 4 - 4; | |
| 718 | fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 756 | |
| 719 | { | 757 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 720 | fault_t fault; | 758 | virt_addr = end_addr; |
| 721 | unsigned int immedL = BITS(inst, 0, 3); | 759 | if (fault) return fault; |
| 722 | unsigned int immedH = BITS(inst, 8, 11); | 760 | |
| 723 | 761 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | |
| 724 | unsigned int Rn = BITS(inst, 16, 19); | 762 | virt_addr = start_addr; |
| 725 | unsigned int addr; | 763 | if (fault) return fault; |
| 726 | 764 | ||
| 727 | unsigned int offset_8 = (immedH << 4) | immedL; | 765 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 728 | if (U_BIT) { | 766 | cpu->Reg[Rn] += count * 4; |
| 729 | addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; | 767 | } |
| 730 | } else | 768 | return fault; |
| 731 | addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; | 769 | } |
| 732 | #if 0 | 770 | |
| 733 | if (Rn == 15) { | 771 | fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 734 | addr += 8; | 772 | fault_t fault; |
| 735 | } | 773 | unsigned int Rn = BITS(inst, 16, 19); |
| 736 | #endif | 774 | unsigned int i = BITS(inst, 0, 15); |
| 737 | virt_addr = addr; | 775 | int count = 0; |
| 738 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 776 | while(i) { |
| 739 | return fault; | 777 | if(i & 1) count ++; |
| 740 | } | 778 | i = i >> 1; |
| 741 | 779 | } | |
| 742 | fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 780 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 743 | { | 781 | unsigned int start_addr = rn - count * 4 + 4; |
| 744 | fault_t fault; | 782 | unsigned int end_addr = rn; |
| 745 | unsigned int addr; | 783 | |
| 746 | unsigned int Rn = BITS(inst, 16, 19); | 784 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); |
| 747 | unsigned int Rm = BITS(inst, 0, 3); | 785 | virt_addr = end_addr; |
| 748 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 786 | if (fault) return fault; |
| 749 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 787 | |
| 750 | //if (Rn == 15) rn += 8; | 788 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); |
| 751 | //if (Rm == 15) rm += 8; | 789 | if (fault) return fault; |
| 752 | if (U_BIT) { | 790 | virt_addr = start_addr; |
| 753 | addr = rn + rm; | 791 | |
| 754 | } else | 792 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 755 | addr = rn - rm; | 793 | cpu->Reg[Rn] -= count * 4; |
| 756 | if(BIT(inst, 20)){ /* L BIT */ | 794 | } |
| 757 | } | 795 | return fault; |
| 758 | if(BIT(inst, 6)){ /* Sign Bit */ | 796 | } |
| 759 | } | 797 | |
| 760 | if(BIT(inst, 5)){ /* Half Bit */ | 798 | fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { |
| 761 | } | 799 | fault_t fault; |
| 762 | virt_addr = addr; | 800 | unsigned int shift = BITS(inst, 5, 6); |
| 763 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 801 | unsigned int shift_imm = BITS(inst, 7, 11); |
| 764 | return fault; | 802 | unsigned int Rn = BITS(inst, 16, 19); |
| 765 | } | 803 | unsigned int Rm = BITS(inst, 0, 3); |
| 766 | 804 | unsigned int index; | |
| 767 | fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 805 | unsigned int addr; |
| 768 | { | 806 | |
| 769 | fault_t fault; | 807 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 770 | unsigned int Rn = BITS(inst, 16, 19); | 808 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 771 | unsigned int immedH = BITS(inst, 8, 11); | 809 | switch (shift) { |
| 772 | unsigned int immedL = BITS(inst, 0, 3); | 810 | case 0: |
| 773 | unsigned int addr; | 811 | index = rm << shift_imm; |
| 774 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 812 | break; |
| 775 | //if (Rn == 15) rn += 8; | 813 | case 1: |
| 776 | 814 | if (shift_imm == 0) { | |
| 777 | // DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__); | 815 | index = 0; |
| 778 | unsigned int offset_8 = (immedH << 4) | immedL; | 816 | } else { |
| 779 | if (U_BIT) { | 817 | index = rm >> shift_imm; |
| 780 | addr = rn + offset_8; | 818 | } |
| 781 | } else | 819 | break; |
| 782 | addr = rn - offset_8; | 820 | case 2: |
| 783 | 821 | if (shift_imm == 0){ // ASR #32 | |
| 784 | virt_addr = addr; | 822 | if (rm >> 31) |
| 785 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 823 | index = 0xFFFFFFFF; |
| 786 | if (fault) return fault; | 824 | else |
| 787 | 825 | index = 0; | |
| 788 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 826 | } |
| 789 | cpu->Reg[Rn] = addr; | 827 | else { |
| 790 | } | 828 | index = static_cast<int>(rm) >> shift_imm; |
| 791 | return fault; | 829 | } |
| 792 | } | 830 | break; |
| 793 | 831 | case 3: | |
| 794 | fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | 832 | DEBUG_MSG; |
| 795 | { | 833 | break; |
| 796 | fault_t fault; | 834 | } |
| 797 | unsigned int Rn = BITS(inst, 16, 19); | 835 | if (U_BIT) { |
| 798 | unsigned int immedH = BITS(inst, 8, 11); | 836 | addr = rn + index; |
| 799 | unsigned int immedL = BITS(inst, 0, 3); | 837 | } else |
| 800 | unsigned int addr; | 838 | addr = rn - index; |
| 801 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 839 | |
| 802 | addr = rn; | 840 | virt_addr = addr; |
| 803 | 841 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | |
| 804 | virt_addr = addr; | 842 | |
| 805 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 843 | return fault; |
| 806 | if (fault) return fault; | 844 | } |
| 807 | 845 | ||
| 808 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 846 | #define ISNEG(n) (n < 0) |
| 809 | unsigned int offset_8 = (immedH << 4) | immedL; | 847 | #define ISPOS(n) (n >= 0) |
| 810 | if (U_BIT) { | ||
| 811 | rn += offset_8; | ||
| 812 | } else { | ||
| 813 | rn -= offset_8; | ||
| 814 | } | ||
| 815 | cpu->Reg[Rn] = rn; | ||
| 816 | } | ||
| 817 | |||
| 818 | return fault; | ||
| 819 | } | ||
| 820 | fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 821 | { | ||
| 822 | fault_t fault; | ||
| 823 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 824 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 825 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 826 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 827 | |||
| 828 | unsigned int addr = rn; | ||
| 829 | virt_addr = addr; | ||
| 830 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 831 | if (fault) return fault; | ||
| 832 | |||
| 833 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 834 | if (U_BIT) { | ||
| 835 | cpu->Reg[Rn] += rm; | ||
| 836 | } else { | ||
| 837 | cpu->Reg[Rn] -= rm; | ||
| 838 | } | ||
| 839 | } | ||
| 840 | return fault; | ||
| 841 | } | ||
| 842 | |||
| 843 | fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 844 | { | ||
| 845 | fault_t fault; | ||
| 846 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 847 | unsigned int i = BITS(inst, 0, 15); | ||
| 848 | int count = 0; | ||
| 849 | while(i) { | ||
| 850 | if(i & 1) count ++; | ||
| 851 | i = i >> 1; | ||
| 852 | } | ||
| 853 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 854 | //if (Rn == 15) rn += 8; | ||
| 855 | unsigned int start_addr = rn - count * 4; | ||
| 856 | unsigned int end_addr = rn - 4; | ||
| 857 | |||
| 858 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 859 | virt_addr = end_addr; | ||
| 860 | if (fault) return fault; | ||
| 861 | |||
| 862 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 863 | virt_addr = start_addr; | ||
| 864 | if (fault) return fault; | ||
| 865 | |||
| 866 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 867 | cpu->Reg[Rn] -= count * 4; | ||
| 868 | } | ||
| 869 | |||
| 870 | return fault; | ||
| 871 | } | ||
| 872 | |||
| 873 | fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 874 | { | ||
| 875 | fault_t fault; | ||
| 876 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 877 | unsigned int i = BITS(inst, 0, 15); | ||
| 878 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 879 | //if (Rn == 15) rn += 8; | ||
| 880 | int count = 0; | ||
| 881 | while(i) { | ||
| 882 | if(i & 1) count ++; | ||
| 883 | i = i >> 1; | ||
| 884 | } | ||
| 885 | |||
| 886 | unsigned int start_addr = rn + 4; | ||
| 887 | unsigned int end_addr = rn + count * 4; | ||
| 888 | |||
| 889 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 890 | virt_addr = end_addr; | ||
| 891 | if (fault) return fault; | ||
| 892 | |||
| 893 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 894 | virt_addr = start_addr; | ||
| 895 | if (fault) return fault; | ||
| 896 | |||
| 897 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 898 | cpu->Reg[Rn] += count * 4; | ||
| 899 | } | ||
| 900 | return fault; | ||
| 901 | } | ||
| 902 | |||
| 903 | fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 904 | { | ||
| 905 | fault_t fault; | ||
| 906 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 907 | unsigned int i = BITS(inst, 0, 15); | ||
| 908 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 909 | int count = 0; | ||
| 910 | while(i) { | ||
| 911 | if(i & 1) count ++; | ||
| 912 | i = i >> 1; | ||
| 913 | } | ||
| 914 | //if (Rn == 15) rn += 8; | ||
| 915 | unsigned int start_addr = rn; | ||
| 916 | unsigned int end_addr = rn + count * 4 - 4; | ||
| 917 | |||
| 918 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 919 | virt_addr = end_addr; | ||
| 920 | if (fault) return fault; | ||
| 921 | |||
| 922 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 923 | virt_addr = start_addr; | ||
| 924 | if (fault) return fault; | ||
| 925 | |||
| 926 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 927 | cpu->Reg[Rn] += count * 4; | ||
| 928 | } | ||
| 929 | return fault; | ||
| 930 | } | ||
| 931 | |||
| 932 | fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 933 | { | ||
| 934 | fault_t fault; | ||
| 935 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 936 | unsigned int i = BITS(inst, 0, 15); | ||
| 937 | int count = 0; | ||
| 938 | while(i) { | ||
| 939 | if(i & 1) count ++; | ||
| 940 | i = i >> 1; | ||
| 941 | } | ||
| 942 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 943 | //if (Rn == 15) rn += 8; | ||
| 944 | unsigned int start_addr = rn - count * 4 + 4; | ||
| 945 | unsigned int end_addr = rn; | ||
| 946 | |||
| 947 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 948 | virt_addr = end_addr; | ||
| 949 | if (fault) return fault; | ||
| 950 | |||
| 951 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 952 | if (fault) return fault; | ||
| 953 | virt_addr = start_addr; | ||
| 954 | |||
| 955 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 956 | cpu->Reg[Rn] -= count * 4; | ||
| 957 | } | ||
| 958 | return fault; | ||
| 959 | } | ||
| 960 | |||
| 961 | fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) | ||
| 962 | { | ||
| 963 | fault_t fault; | ||
| 964 | unsigned int shift = BITS(inst, 5, 6); | ||
| 965 | unsigned int shift_imm = BITS(inst, 7, 11); | ||
| 966 | unsigned int Rn = BITS(inst, 16, 19); | ||
| 967 | unsigned int Rm = BITS(inst, 0, 3); | ||
| 968 | unsigned int index; | ||
| 969 | unsigned int addr; | ||
| 970 | |||
| 971 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | ||
| 972 | //if (Rm == 15) rm += 8; | ||
| 973 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 974 | //if (Rn == 15) rn += 8; | ||
| 975 | switch (shift) { | ||
| 976 | case 0: | ||
| 977 | //DEBUG_MSG; | ||
| 978 | index = rm << shift_imm; | ||
| 979 | break; | ||
| 980 | case 1: | ||
| 981 | // DEBUG_MSG; | ||
| 982 | if (shift_imm == 0) { | ||
| 983 | index = 0; | ||
| 984 | } else { | ||
| 985 | index = rm >> shift_imm; | ||
| 986 | } | ||
| 987 | break; | ||
| 988 | case 2: | ||
| 989 | if (shift_imm == 0){ /* ASR #32 */ | ||
| 990 | if (rm >> 31) | ||
| 991 | index = 0xFFFFFFFF; | ||
| 992 | else | ||
| 993 | index = 0; | ||
| 994 | } | ||
| 995 | else { | ||
| 996 | index = static_cast<int>(rm) >> shift_imm; | ||
| 997 | } | ||
| 998 | break; | ||
| 999 | case 3: | ||
| 1000 | DEBUG_MSG; | ||
| 1001 | break; | ||
| 1002 | } | ||
| 1003 | if (U_BIT) { | ||
| 1004 | addr = rn + index; | ||
| 1005 | } else | ||
| 1006 | addr = rn - index; | ||
| 1007 | virt_addr = addr; | ||
| 1008 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 1009 | return fault; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | #define ISNEG(n) (n < 0) | ||
| 1013 | #define ISPOS(n) (n >= 0) | ||
| 1014 | |||
| 1015 | //enum { | ||
| 1016 | // COND = (1 << 0), | ||
| 1017 | // NON_BRANCH = (1 << 1), | ||
| 1018 | // DIRECT_BRANCH = (1 << 2), | ||
| 1019 | // INDIRECT_BRANCH = (1 << 3), | ||
| 1020 | // CALL = (1 << 4), | ||
| 1021 | // RET = (1 << 5), | ||
| 1022 | // END_OF_PAGE = (1 << 6), | ||
| 1023 | // THUMB = (1 << 7) | ||
| 1024 | //}; | ||
| 1025 | 848 | ||
| 1026 | typedef struct _arm_inst { | 849 | typedef struct _arm_inst { |
| 1027 | unsigned int idx; | 850 | unsigned int idx; |
| 1028 | unsigned int cond; | 851 | unsigned int cond; |
| 1029 | int br; | 852 | int br; |
| 1030 | int load_r15; | 853 | int load_r15; |
| 1031 | char component[0]; | 854 | char component[0]; |
| 1032 | } arm_inst; | 855 | } arm_inst; |
| 1033 | 856 | ||
| 857 | typedef struct generic_arm_inst { | ||
| 858 | u32 Ra; | ||
| 859 | u32 Rm; | ||
| 860 | u32 Rn; | ||
| 861 | u32 Rd; | ||
| 862 | u8 op1; | ||
| 863 | u8 op2; | ||
| 864 | } generic_arm_inst; | ||
| 865 | |||
| 1034 | typedef struct _adc_inst { | 866 | typedef struct _adc_inst { |
| 1035 | unsigned int I; | 867 | unsigned int I; |
| 1036 | unsigned int S; | 868 | unsigned int S; |
| 1037 | unsigned int Rn; | 869 | unsigned int Rn; |
| 1038 | unsigned int Rd; | 870 | unsigned int Rd; |
| 1039 | unsigned int shifter_operand; | 871 | unsigned int shifter_operand; |
| 1040 | shtop_fp_t shtop_func; | 872 | shtop_fp_t shtop_func; |
| 1041 | } adc_inst; | 873 | } adc_inst; |
| 1042 | 874 | ||
| 1043 | typedef struct _add_inst { | 875 | typedef struct _add_inst { |
| 1044 | unsigned int I; | 876 | unsigned int I; |
| 1045 | unsigned int S; | 877 | unsigned int S; |
| 1046 | unsigned int Rn; | 878 | unsigned int Rn; |
| 1047 | unsigned int Rd; | 879 | unsigned int Rd; |
| 1048 | unsigned int shifter_operand; | 880 | unsigned int shifter_operand; |
| 1049 | shtop_fp_t shtop_func; | 881 | shtop_fp_t shtop_func; |
| 1050 | } add_inst; | 882 | } add_inst; |
| 1051 | 883 | ||
| 1052 | typedef struct _orr_inst { | 884 | typedef struct _orr_inst { |
| 1053 | unsigned int I; | 885 | unsigned int I; |
| 1054 | unsigned int S; | 886 | unsigned int S; |
| 1055 | unsigned int Rn; | 887 | unsigned int Rn; |
| 1056 | unsigned int Rd; | 888 | unsigned int Rd; |
| 1057 | unsigned int shifter_operand; | 889 | unsigned int shifter_operand; |
| 1058 | shtop_fp_t shtop_func; | 890 | shtop_fp_t shtop_func; |
| 1059 | } orr_inst; | 891 | } orr_inst; |
| 1060 | 892 | ||
| 1061 | typedef struct _and_inst { | 893 | typedef struct _and_inst { |
| 1062 | unsigned int I; | 894 | unsigned int I; |
| 1063 | unsigned int S; | 895 | unsigned int S; |
| 1064 | unsigned int Rn; | 896 | unsigned int Rn; |
| 1065 | unsigned int Rd; | 897 | unsigned int Rd; |
| 1066 | unsigned int shifter_operand; | 898 | unsigned int shifter_operand; |
| 1067 | shtop_fp_t shtop_func; | 899 | shtop_fp_t shtop_func; |
| 1068 | } and_inst; | 900 | } and_inst; |
| 1069 | 901 | ||
| 1070 | typedef struct _eor_inst { | 902 | typedef struct _eor_inst { |
| 1071 | unsigned int I; | 903 | unsigned int I; |
| 1072 | unsigned int S; | 904 | unsigned int S; |
| 1073 | unsigned int Rn; | 905 | unsigned int Rn; |
| 1074 | unsigned int Rd; | 906 | unsigned int Rd; |
| 1075 | unsigned int shifter_operand; | 907 | unsigned int shifter_operand; |
| 1076 | shtop_fp_t shtop_func; | 908 | shtop_fp_t shtop_func; |
| 1077 | } eor_inst; | 909 | } eor_inst; |
| 1078 | 910 | ||
| 1079 | typedef struct _bbl_inst { | 911 | typedef struct _bbl_inst { |
| 1080 | unsigned int L; | 912 | unsigned int L; |
| 1081 | int signed_immed_24; | 913 | int signed_immed_24; |
| 1082 | unsigned int next_addr; | 914 | unsigned int next_addr; |
| 1083 | unsigned int jmp_addr; | 915 | unsigned int jmp_addr; |
| 1084 | } bbl_inst; | 916 | } bbl_inst; |
| 1085 | 917 | ||
| 1086 | typedef struct _bx_inst { | 918 | typedef struct _bx_inst { |
| 1087 | unsigned int Rm; | 919 | unsigned int Rm; |
| 1088 | } bx_inst; | 920 | } bx_inst; |
| 1089 | 921 | ||
| 1090 | typedef struct _blx_inst { | 922 | typedef struct _blx_inst { |
| 1091 | union { | 923 | union { |
| 1092 | int32_t signed_immed_24; | 924 | int32_t signed_immed_24; |
| 1093 | uint32_t Rm; | 925 | uint32_t Rm; |
| 1094 | } val; | 926 | } val; |
| 1095 | unsigned int inst; | 927 | unsigned int inst; |
| 1096 | } blx_inst; | 928 | } blx_inst; |
| 1097 | 929 | ||
| 1098 | typedef struct _clz_inst { | 930 | typedef struct _clz_inst { |
| 1099 | unsigned int Rm; | 931 | unsigned int Rm; |
| 1100 | unsigned int Rd; | 932 | unsigned int Rd; |
| 1101 | } clz_inst; | 933 | } clz_inst; |
| 1102 | 934 | ||
| 1103 | typedef struct _cps_inst { | 935 | typedef struct _cps_inst { |
| 1104 | unsigned int imod0; | 936 | unsigned int imod0; |
| 1105 | unsigned int imod1; | 937 | unsigned int imod1; |
| 1106 | unsigned int mmod; | 938 | unsigned int mmod; |
| 1107 | unsigned int A, I, F; | 939 | unsigned int A, I, F; |
| 1108 | unsigned int mode; | 940 | unsigned int mode; |
| 1109 | } cps_inst; | 941 | } cps_inst; |
| 1110 | 942 | ||
| 1111 | typedef struct _clrex_inst { | 943 | typedef struct _clrex_inst { |
| 1112 | } clrex_inst; | 944 | } clrex_inst; |
| 1113 | 945 | ||
| 1114 | typedef struct _cpy_inst { | 946 | typedef struct _cpy_inst { |
| 1115 | unsigned int Rm; | 947 | unsigned int Rm; |
| 1116 | unsigned int Rd; | 948 | unsigned int Rd; |
| 1117 | } cpy_inst; | 949 | } cpy_inst; |
| 1118 | 950 | ||
| 1119 | typedef struct _bic_inst { | 951 | typedef struct _bic_inst { |
| 1120 | unsigned int I; | 952 | unsigned int I; |
| 1121 | unsigned int S; | 953 | unsigned int S; |
| 1122 | unsigned int Rn; | 954 | unsigned int Rn; |
| 1123 | unsigned int Rd; | 955 | unsigned int Rd; |
| 1124 | unsigned int shifter_operand; | 956 | unsigned int shifter_operand; |
| 1125 | shtop_fp_t shtop_func; | 957 | shtop_fp_t shtop_func; |
| 1126 | } bic_inst; | 958 | } bic_inst; |
| 1127 | 959 | ||
| 1128 | typedef struct _sub_inst { | 960 | typedef struct _sub_inst { |
| 1129 | unsigned int I; | 961 | unsigned int I; |
| 1130 | unsigned int S; | 962 | unsigned int S; |
| 1131 | unsigned int Rn; | 963 | unsigned int Rn; |
| 1132 | unsigned int Rd; | 964 | unsigned int Rd; |
| 1133 | unsigned int shifter_operand; | 965 | unsigned int shifter_operand; |
| 1134 | shtop_fp_t shtop_func; | 966 | shtop_fp_t shtop_func; |
| 1135 | } sub_inst; | 967 | } sub_inst; |
| 1136 | 968 | ||
| 1137 | typedef struct _tst_inst { | 969 | typedef struct _tst_inst { |
| 1138 | unsigned int I; | 970 | unsigned int I; |
| 1139 | unsigned int S; | 971 | unsigned int S; |
| 1140 | unsigned int Rn; | 972 | unsigned int Rn; |
| 1141 | unsigned int Rd; | 973 | unsigned int Rd; |
| 1142 | unsigned int shifter_operand; | 974 | unsigned int shifter_operand; |
| 1143 | shtop_fp_t shtop_func; | 975 | shtop_fp_t shtop_func; |
| 1144 | } tst_inst; | 976 | } tst_inst; |
| 1145 | 977 | ||
| 1146 | typedef struct _cmn_inst { | 978 | typedef struct _cmn_inst { |
| 1147 | unsigned int I; | 979 | unsigned int I; |
| 1148 | //unsigned int S; | 980 | unsigned int Rn; |
| 1149 | unsigned int Rn; | 981 | unsigned int shifter_operand; |
| 1150 | //unsigned int Rd; | 982 | shtop_fp_t shtop_func; |
| 1151 | unsigned int shifter_operand; | ||
| 1152 | shtop_fp_t shtop_func; | ||
| 1153 | } cmn_inst; | 983 | } cmn_inst; |
| 1154 | 984 | ||
| 1155 | typedef struct _teq_inst { | 985 | typedef struct _teq_inst { |
| 1156 | unsigned int I; | 986 | unsigned int I; |
| 1157 | unsigned int Rn; | 987 | unsigned int Rn; |
| 1158 | unsigned int shifter_operand; | 988 | unsigned int shifter_operand; |
| 1159 | shtop_fp_t shtop_func; | 989 | shtop_fp_t shtop_func; |
| 1160 | } teq_inst; | 990 | } teq_inst; |
| 1161 | 991 | ||
| 1162 | typedef struct _stm_inst { | 992 | typedef struct _stm_inst { |
| 1163 | unsigned int inst; | 993 | unsigned int inst; |
| 1164 | } stm_inst; | 994 | } stm_inst; |
| 1165 | 995 | ||
| 1166 | struct bkpt_inst { | 996 | struct bkpt_inst { |
| 1167 | }; | 997 | }; |
| 1168 | 998 | ||
| 1169 | struct blx1_inst { | 999 | struct blx1_inst { |
| 1170 | unsigned int addr; | 1000 | unsigned int addr; |
| 1171 | }; | 1001 | }; |
| 1172 | 1002 | ||
| 1173 | struct blx2_inst { | 1003 | struct blx2_inst { |
| 1174 | unsigned int Rm; | 1004 | unsigned int Rm; |
| 1175 | }; | 1005 | }; |
| 1176 | 1006 | ||
| 1177 | typedef struct _stc_inst { | 1007 | typedef struct _stc_inst { |
| @@ -1181,1965 +1011,2188 @@ typedef struct _ldc_inst { | |||
| 1181 | } ldc_inst; | 1011 | } ldc_inst; |
| 1182 | 1012 | ||
| 1183 | typedef struct _swi_inst { | 1013 | typedef struct _swi_inst { |
| 1184 | unsigned int num; | 1014 | unsigned int num; |
| 1185 | } swi_inst; | 1015 | } swi_inst; |
| 1186 | 1016 | ||
| 1187 | typedef struct _cmp_inst { | 1017 | typedef struct _cmp_inst { |
| 1188 | unsigned int I; | 1018 | unsigned int I; |
| 1189 | unsigned int Rn; | 1019 | unsigned int Rn; |
| 1190 | unsigned int shifter_operand; | 1020 | unsigned int shifter_operand; |
| 1191 | shtop_fp_t shtop_func; | 1021 | shtop_fp_t shtop_func; |
| 1192 | } cmp_inst; | 1022 | } cmp_inst; |
| 1193 | 1023 | ||
| 1194 | typedef struct _mov_inst { | 1024 | typedef struct _mov_inst { |
| 1195 | unsigned int I; | 1025 | unsigned int I; |
| 1196 | unsigned int S; | 1026 | unsigned int S; |
| 1197 | unsigned int Rd; | 1027 | unsigned int Rd; |
| 1198 | unsigned int shifter_operand; | 1028 | unsigned int shifter_operand; |
| 1199 | shtop_fp_t shtop_func; | 1029 | shtop_fp_t shtop_func; |
| 1200 | } mov_inst; | 1030 | } mov_inst; |
| 1201 | 1031 | ||
| 1202 | typedef struct _mvn_inst { | 1032 | typedef struct _mvn_inst { |
| 1203 | unsigned int I; | 1033 | unsigned int I; |
| 1204 | unsigned int S; | 1034 | unsigned int S; |
| 1205 | unsigned int Rd; | 1035 | unsigned int Rd; |
| 1206 | unsigned int shifter_operand; | 1036 | unsigned int shifter_operand; |
| 1207 | shtop_fp_t shtop_func; | 1037 | shtop_fp_t shtop_func; |
| 1208 | } mvn_inst; | 1038 | } mvn_inst; |
| 1209 | 1039 | ||
| 1210 | typedef struct _rev_inst { | 1040 | typedef struct _rev_inst { |
| 1211 | unsigned int Rd; | 1041 | unsigned int Rd; |
| 1212 | unsigned int Rm; | 1042 | unsigned int Rm; |
| 1213 | } rev_inst; | 1043 | } rev_inst; |
| 1214 | 1044 | ||
| 1215 | typedef struct _rsb_inst { | 1045 | typedef struct _rsb_inst { |
| 1216 | unsigned int I; | 1046 | unsigned int I; |
| 1217 | unsigned int S; | 1047 | unsigned int S; |
| 1218 | unsigned int Rn; | 1048 | unsigned int Rn; |
| 1219 | unsigned int Rd; | 1049 | unsigned int Rd; |
| 1220 | unsigned int shifter_operand; | 1050 | unsigned int shifter_operand; |
| 1221 | shtop_fp_t shtop_func; | 1051 | shtop_fp_t shtop_func; |
| 1222 | } rsb_inst; | 1052 | } rsb_inst; |
| 1223 | 1053 | ||
| 1224 | typedef struct _rsc_inst { | 1054 | typedef struct _rsc_inst { |
| 1225 | unsigned int I; | 1055 | unsigned int I; |
| 1226 | unsigned int S; | 1056 | unsigned int S; |
| 1227 | unsigned int Rn; | 1057 | unsigned int Rn; |
| 1228 | unsigned int Rd; | 1058 | unsigned int Rd; |
| 1229 | unsigned int shifter_operand; | 1059 | unsigned int shifter_operand; |
| 1230 | shtop_fp_t shtop_func; | 1060 | shtop_fp_t shtop_func; |
| 1231 | } rsc_inst; | 1061 | } rsc_inst; |
| 1232 | 1062 | ||
| 1233 | typedef struct _sbc_inst { | 1063 | typedef struct _sbc_inst { |
| 1234 | unsigned int I; | 1064 | unsigned int I; |
| 1235 | unsigned int S; | 1065 | unsigned int S; |
| 1236 | unsigned int Rn; | 1066 | unsigned int Rn; |
| 1237 | unsigned int Rd; | 1067 | unsigned int Rd; |
| 1238 | unsigned int shifter_operand; | 1068 | unsigned int shifter_operand; |
| 1239 | shtop_fp_t shtop_func; | 1069 | shtop_fp_t shtop_func; |
| 1240 | } sbc_inst; | 1070 | } sbc_inst; |
| 1241 | 1071 | ||
| 1242 | typedef struct _mul_inst { | 1072 | typedef struct _mul_inst { |
| 1243 | unsigned int S; | 1073 | unsigned int S; |
| 1244 | unsigned int Rd; | 1074 | unsigned int Rd; |
| 1245 | unsigned int Rs; | 1075 | unsigned int Rs; |
| 1246 | unsigned int Rm; | 1076 | unsigned int Rm; |
| 1247 | } mul_inst; | 1077 | } mul_inst; |
| 1248 | 1078 | ||
| 1249 | typedef struct _smul_inst { | 1079 | typedef struct _smul_inst { |
| 1250 | unsigned int Rd; | 1080 | unsigned int Rd; |
| 1251 | unsigned int Rs; | 1081 | unsigned int Rs; |
| 1252 | unsigned int Rm; | 1082 | unsigned int Rm; |
| 1253 | unsigned int x; | 1083 | unsigned int x; |
| 1254 | unsigned int y; | 1084 | unsigned int y; |
| 1255 | } smul_inst; | 1085 | } smul_inst; |
| 1256 | 1086 | ||
| 1257 | typedef struct _umull_inst { | 1087 | typedef struct _umull_inst { |
| 1258 | unsigned int S; | 1088 | unsigned int S; |
| 1259 | unsigned int RdHi; | 1089 | unsigned int RdHi; |
| 1260 | unsigned int RdLo; | 1090 | unsigned int RdLo; |
| 1261 | unsigned int Rs; | 1091 | unsigned int Rs; |
| 1262 | unsigned int Rm; | 1092 | unsigned int Rm; |
| 1263 | } umull_inst; | 1093 | } umull_inst; |
| 1264 | typedef struct _smlad_inst { | 1094 | typedef struct _smlad_inst { |
| 1265 | unsigned int m; | 1095 | unsigned int m; |
| 1266 | unsigned int Rm; | 1096 | unsigned int Rm; |
| 1267 | unsigned int Rd; | 1097 | unsigned int Rd; |
| 1268 | unsigned int Ra; | 1098 | unsigned int Ra; |
| 1269 | unsigned int Rn; | 1099 | unsigned int Rn; |
| 1270 | } smlad_inst; | 1100 | } smlad_inst; |
| 1271 | 1101 | ||
| 1272 | typedef struct _smla_inst { | 1102 | typedef struct _smla_inst { |
| 1273 | unsigned int x; | 1103 | unsigned int x; |
| 1274 | unsigned int y; | 1104 | unsigned int y; |
| 1275 | unsigned int Rm; | 1105 | unsigned int Rm; |
| 1276 | unsigned int Rd; | 1106 | unsigned int Rd; |
| 1277 | unsigned int Rs; | 1107 | unsigned int Rs; |
| 1278 | unsigned int Rn; | 1108 | unsigned int Rn; |
| 1279 | } smla_inst; | 1109 | } smla_inst; |
| 1280 | 1110 | ||
| 1111 | typedef struct ssat_inst { | ||
| 1112 | unsigned int Rn; | ||
| 1113 | unsigned int Rd; | ||
| 1114 | unsigned int imm5; | ||
| 1115 | unsigned int sat_imm; | ||
| 1116 | unsigned int shift_type; | ||
| 1117 | } ssat_inst; | ||
| 1118 | |||
| 1119 | typedef struct umaal_inst { | ||
| 1120 | unsigned int Rn; | ||
| 1121 | unsigned int Rm; | ||
| 1122 | unsigned int RdHi; | ||
| 1123 | unsigned int RdLo; | ||
| 1124 | } umaal_inst; | ||
| 1125 | |||
| 1281 | typedef struct _umlal_inst { | 1126 | typedef struct _umlal_inst { |
| 1282 | unsigned int S; | 1127 | unsigned int S; |
| 1283 | unsigned int Rm; | 1128 | unsigned int Rm; |
| 1284 | unsigned int Rs; | 1129 | unsigned int Rs; |
| 1285 | unsigned int RdHi; | 1130 | unsigned int RdHi; |
| 1286 | unsigned int RdLo; | 1131 | unsigned int RdLo; |
| 1287 | } umlal_inst; | 1132 | } umlal_inst; |
| 1288 | 1133 | ||
| 1289 | typedef struct _smlal_inst { | 1134 | typedef struct _smlal_inst { |
| 1290 | unsigned int S; | 1135 | unsigned int S; |
| 1291 | unsigned int Rm; | 1136 | unsigned int Rm; |
| 1292 | unsigned int Rs; | 1137 | unsigned int Rs; |
| 1293 | unsigned int RdHi; | 1138 | unsigned int RdHi; |
| 1294 | unsigned int RdLo; | 1139 | unsigned int RdLo; |
| 1295 | } smlal_inst; | 1140 | } smlal_inst; |
| 1296 | 1141 | ||
| 1297 | typedef struct _mla_inst { | 1142 | typedef struct _mla_inst { |
| 1298 | unsigned int S; | 1143 | unsigned int S; |
| 1299 | unsigned int Rn; | 1144 | unsigned int Rn; |
| 1300 | unsigned int Rd; | 1145 | unsigned int Rd; |
| 1301 | unsigned int Rs; | 1146 | unsigned int Rs; |
| 1302 | unsigned int Rm; | 1147 | unsigned int Rm; |
| 1303 | } mla_inst; | 1148 | } mla_inst; |
| 1304 | 1149 | ||
| 1305 | typedef struct _mrc_inst { | 1150 | typedef struct _mrc_inst { |
| 1306 | unsigned int opcode_1; | 1151 | unsigned int opcode_1; |
| 1307 | unsigned int opcode_2; | 1152 | unsigned int opcode_2; |
| 1308 | unsigned int cp_num; | 1153 | unsigned int cp_num; |
| 1309 | unsigned int crn; | 1154 | unsigned int crn; |
| 1310 | unsigned int crm; | 1155 | unsigned int crm; |
| 1311 | unsigned int Rd; | 1156 | unsigned int Rd; |
| 1312 | unsigned int inst; | 1157 | unsigned int inst; |
| 1313 | } mrc_inst; | 1158 | } mrc_inst; |
| 1314 | 1159 | ||
| 1315 | typedef struct _mcr_inst { | 1160 | typedef struct _mcr_inst { |
| 1316 | unsigned int opcode_1; | 1161 | unsigned int opcode_1; |
| 1317 | unsigned int opcode_2; | 1162 | unsigned int opcode_2; |
| 1318 | unsigned int cp_num; | 1163 | unsigned int cp_num; |
| 1319 | unsigned int crn; | 1164 | unsigned int crn; |
| 1320 | unsigned int crm; | 1165 | unsigned int crm; |
| 1321 | unsigned int Rd; | 1166 | unsigned int Rd; |
| 1322 | unsigned int inst; | 1167 | unsigned int inst; |
| 1323 | } mcr_inst; | 1168 | } mcr_inst; |
| 1324 | 1169 | ||
| 1325 | typedef struct _mrs_inst { | 1170 | typedef struct _mrs_inst { |
| 1326 | unsigned int R; | 1171 | unsigned int R; |
| 1327 | unsigned int Rd; | 1172 | unsigned int Rd; |
| 1328 | } mrs_inst; | 1173 | } mrs_inst; |
| 1329 | 1174 | ||
| 1330 | typedef struct _msr_inst { | 1175 | typedef struct _msr_inst { |
| 1331 | unsigned int field_mask; | 1176 | unsigned int field_mask; |
| 1332 | unsigned int R; | 1177 | unsigned int R; |
| 1333 | unsigned int inst; | 1178 | unsigned int inst; |
| 1334 | } msr_inst; | 1179 | } msr_inst; |
| 1335 | 1180 | ||
| 1336 | typedef struct _pld_inst { | 1181 | typedef struct _pld_inst { |
| 1337 | } pld_inst; | 1182 | } pld_inst; |
| 1338 | 1183 | ||
| 1339 | typedef struct _sxtb_inst { | 1184 | typedef struct _sxtb_inst { |
| 1340 | unsigned int Rd; | 1185 | unsigned int Rd; |
| 1341 | unsigned int Rm; | 1186 | unsigned int Rm; |
| 1342 | unsigned int rotate; | 1187 | unsigned int rotate; |
| 1343 | } sxtb_inst; | 1188 | } sxtb_inst; |
| 1344 | 1189 | ||
| 1345 | typedef struct _sxtab_inst { | 1190 | typedef struct _sxtab_inst { |
| 1346 | unsigned int Rd; | 1191 | unsigned int Rd; |
| 1347 | unsigned int Rn; | 1192 | unsigned int Rn; |
| 1348 | unsigned int Rm; | 1193 | unsigned int Rm; |
| 1349 | unsigned rotate; | 1194 | unsigned rotate; |
| 1350 | } sxtab_inst; | 1195 | } sxtab_inst; |
| 1351 | 1196 | ||
| 1352 | typedef struct _sxtah_inst { | 1197 | typedef struct _sxtah_inst { |
| 1353 | unsigned int Rd; | 1198 | unsigned int Rd; |
| 1354 | unsigned int Rn; | 1199 | unsigned int Rn; |
| 1355 | unsigned int Rm; | 1200 | unsigned int Rm; |
| 1356 | unsigned int rotate; | 1201 | unsigned int rotate; |
| 1357 | } sxtah_inst; | 1202 | } sxtah_inst; |
| 1358 | 1203 | ||
| 1359 | typedef struct _sxth_inst { | 1204 | typedef struct _sxth_inst { |
| 1360 | unsigned int Rd; | 1205 | unsigned int Rd; |
| 1361 | unsigned int Rm; | 1206 | unsigned int Rm; |
| 1362 | unsigned int rotate; | 1207 | unsigned int rotate; |
| 1363 | } sxth_inst; | 1208 | } sxth_inst; |
| 1364 | 1209 | ||
| 1365 | typedef struct _uxtab_inst { | 1210 | typedef struct _uxtab_inst { |
| 1366 | unsigned int Rn; | 1211 | unsigned int Rn; |
| 1367 | unsigned int Rd; | 1212 | unsigned int Rd; |
| 1368 | unsigned int rotate; | 1213 | unsigned int rotate; |
| 1369 | unsigned int Rm; | 1214 | unsigned int Rm; |
| 1370 | } uxtab_inst; | 1215 | } uxtab_inst; |
| 1371 | 1216 | ||
| 1372 | typedef struct _uxtah_inst { | 1217 | typedef struct _uxtah_inst { |
| 1373 | unsigned int Rn; | 1218 | unsigned int Rn; |
| 1374 | unsigned int Rd; | 1219 | unsigned int Rd; |
| 1375 | unsigned int rotate; | 1220 | unsigned int rotate; |
| 1376 | unsigned int Rm; | 1221 | unsigned int Rm; |
| 1377 | } uxtah_inst; | 1222 | } uxtah_inst; |
| 1378 | 1223 | ||
| 1379 | typedef struct _uxth_inst { | 1224 | typedef struct _uxth_inst { |
| 1380 | unsigned int Rd; | 1225 | unsigned int Rd; |
| 1381 | unsigned int Rm; | 1226 | unsigned int Rm; |
| 1382 | unsigned int rotate; | 1227 | unsigned int rotate; |
| 1383 | } uxth_inst; | 1228 | } uxth_inst; |
| 1384 | 1229 | ||
| 1385 | typedef struct _cdp_inst { | 1230 | typedef struct _cdp_inst { |
| 1386 | unsigned int opcode_1; | 1231 | unsigned int opcode_1; |
| 1387 | unsigned int CRn; | 1232 | unsigned int CRn; |
| 1388 | unsigned int CRd; | 1233 | unsigned int CRd; |
| 1389 | unsigned int cp_num; | 1234 | unsigned int cp_num; |
| 1390 | unsigned int opcode_2; | 1235 | unsigned int opcode_2; |
| 1391 | unsigned int CRm; | 1236 | unsigned int CRm; |
| 1392 | uint32 inst; | 1237 | uint32 inst; |
| 1393 | }cdp_inst; | 1238 | }cdp_inst; |
| 1394 | 1239 | ||
| 1395 | typedef struct _uxtb_inst { | 1240 | typedef struct _uxtb_inst { |
| 1396 | unsigned int Rd; | 1241 | unsigned int Rd; |
| 1397 | unsigned int Rm; | 1242 | unsigned int Rm; |
| 1398 | unsigned int rotate; | 1243 | unsigned int rotate; |
| 1399 | } uxtb_inst; | 1244 | } uxtb_inst; |
| 1400 | 1245 | ||
| 1401 | typedef struct _swp_inst { | 1246 | typedef struct _swp_inst { |
| 1402 | unsigned int Rn; | 1247 | unsigned int Rn; |
| 1403 | unsigned int Rd; | 1248 | unsigned int Rd; |
| 1404 | unsigned int Rm; | 1249 | unsigned int Rm; |
| 1405 | } swp_inst; | 1250 | } swp_inst; |
| 1406 | 1251 | ||
| 1407 | typedef struct _b_2_thumb { | 1252 | typedef struct _b_2_thumb { |
| 1408 | unsigned int imm; | 1253 | unsigned int imm; |
| 1409 | }b_2_thumb; | 1254 | }b_2_thumb; |
| 1410 | typedef struct _b_cond_thumb { | 1255 | typedef struct _b_cond_thumb { |
| 1411 | unsigned int imm; | 1256 | unsigned int imm; |
| 1412 | unsigned int cond; | 1257 | unsigned int cond; |
| 1413 | }b_cond_thumb; | 1258 | }b_cond_thumb; |
| 1414 | 1259 | ||
| 1415 | typedef struct _bl_1_thumb { | 1260 | typedef struct _bl_1_thumb { |
| 1416 | unsigned int imm; | 1261 | unsigned int imm; |
| 1417 | }bl_1_thumb; | 1262 | }bl_1_thumb; |
| 1418 | typedef struct _bl_2_thumb { | 1263 | typedef struct _bl_2_thumb { |
| 1419 | unsigned int imm; | 1264 | unsigned int imm; |
| 1420 | }bl_2_thumb; | 1265 | }bl_2_thumb; |
| 1421 | typedef struct _blx_1_thumb { | 1266 | typedef struct _blx_1_thumb { |
| 1422 | unsigned int imm; | 1267 | unsigned int imm; |
| 1423 | unsigned int instr; | 1268 | unsigned int instr; |
| 1424 | }blx_1_thumb; | 1269 | }blx_1_thumb; |
| 1425 | 1270 | ||
| 1271 | typedef struct _pkh_inst { | ||
| 1272 | u32 Rm; | ||
| 1273 | u32 Rn; | ||
| 1274 | u32 Rd; | ||
| 1275 | u8 imm; | ||
| 1276 | } pkh_inst; | ||
| 1277 | |||
| 1426 | typedef arm_inst * ARM_INST_PTR; | 1278 | typedef arm_inst * ARM_INST_PTR; |
| 1427 | 1279 | ||
| 1428 | #define CACHE_BUFFER_SIZE (64 * 1024 * 2000) | 1280 | #define CACHE_BUFFER_SIZE (64 * 1024 * 2000) |
| 1429 | char inst_buf[CACHE_BUFFER_SIZE]; | 1281 | char inst_buf[CACHE_BUFFER_SIZE]; |
| 1430 | int top = 0; | 1282 | int top = 0; |
| 1431 | inline void *AllocBuffer(unsigned int size) | 1283 | inline void *AllocBuffer(unsigned int size) { |
| 1432 | { | 1284 | int start = top; |
| 1433 | int start = top; | 1285 | top += size; |
| 1434 | top += size; | 1286 | if (top > CACHE_BUFFER_SIZE) { |
| 1435 | if (top > CACHE_BUFFER_SIZE) { | 1287 | LOG_ERROR(Core_ARM11, "inst_buf is full"); |
| 1436 | DEBUG_LOG(ARM11, "inst_buf is full\n"); | 1288 | CITRA_IGNORE_EXIT(-1); |
| 1437 | CITRA_IGNORE_EXIT(-1); | 1289 | } |
| 1438 | } | 1290 | return (void *)&inst_buf[start]; |
| 1439 | return (void *)&inst_buf[start]; | 1291 | } |
| 1440 | } | 1292 | |
| 1441 | 1293 | int CondPassed(arm_processor *cpu, unsigned int cond) { | |
| 1442 | int CondPassed(arm_processor *cpu, unsigned int cond) | 1294 | #define NFLAG cpu->NFlag |
| 1443 | { | 1295 | #define ZFLAG cpu->ZFlag |
| 1444 | #define NFLAG cpu->NFlag | 1296 | #define CFLAG cpu->CFlag |
| 1445 | #define ZFLAG cpu->ZFlag | 1297 | #define VFLAG cpu->VFlag |
| 1446 | #define CFLAG cpu->CFlag | 1298 | |
| 1447 | #define VFLAG cpu->VFlag | 1299 | int temp; |
| 1448 | int temp; | 1300 | |
| 1449 | switch (cond) { | 1301 | switch (cond) { |
| 1450 | case 0x0: | 1302 | case 0x0: |
| 1451 | temp = ZFLAG; | 1303 | temp = ZFLAG; |
| 1452 | break; | 1304 | break; |
| 1453 | case 0x1: /* NE */ | 1305 | case 0x1: // NE |
| 1454 | temp = !ZFLAG; | 1306 | temp = !ZFLAG; |
| 1455 | break; | 1307 | break; |
| 1456 | case 0x6: /* VS */ | 1308 | case 0x6: // VS |
| 1457 | temp = VFLAG; | 1309 | temp = VFLAG; |
| 1458 | break; | 1310 | break; |
| 1459 | case 0x7: /* VC */ | 1311 | case 0x7: // VC |
| 1460 | temp = !VFLAG; | 1312 | temp = !VFLAG; |
| 1461 | break; | 1313 | break; |
| 1462 | case 0x4: /* MI */ | 1314 | case 0x4: // MI |
| 1463 | temp = NFLAG; | 1315 | temp = NFLAG; |
| 1464 | break; | 1316 | break; |
| 1465 | case 0x5: /* PL */ | 1317 | case 0x5: // PL |
| 1466 | temp = !NFLAG; | 1318 | temp = !NFLAG; |
| 1467 | break; | 1319 | break; |
| 1468 | case 0x2: /* CS */ | 1320 | case 0x2: // CS |
| 1469 | temp = CFLAG; | 1321 | temp = CFLAG; |
| 1470 | break; | 1322 | break; |
| 1471 | case 0x3: /* CC */ | 1323 | case 0x3: // CC |
| 1472 | temp = !CFLAG; | 1324 | temp = !CFLAG; |
| 1473 | break; | 1325 | break; |
| 1474 | case 0x8: /* HI */ | 1326 | case 0x8: // HI |
| 1475 | temp = (CFLAG && !ZFLAG); | 1327 | temp = (CFLAG && !ZFLAG); |
| 1476 | break; | 1328 | break; |
| 1477 | case 0x9: /* LS */ | 1329 | case 0x9: // LS |
| 1478 | temp = (!CFLAG || ZFLAG); | 1330 | temp = (!CFLAG || ZFLAG); |
| 1479 | break; | 1331 | break; |
| 1480 | case 0xa: /* GE */ | 1332 | case 0xa: // GE |
| 1481 | temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); | 1333 | temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); |
| 1482 | break; | 1334 | break; |
| 1483 | case 0xb: /* LT */ | 1335 | case 0xb: // LT |
| 1484 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); | 1336 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); |
| 1485 | break; | 1337 | break; |
| 1486 | case 0xc: /* GT */ | 1338 | case 0xc: // GT |
| 1487 | temp = ((!NFLAG && !VFLAG && !ZFLAG) | 1339 | temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); |
| 1488 | || (NFLAG && VFLAG && !ZFLAG)); | 1340 | break; |
| 1489 | break; | 1341 | case 0xd: // LE |
| 1490 | case 0xd: /* LE */ | 1342 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; |
| 1491 | temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) | 1343 | break; |
| 1492 | || ZFLAG; | 1344 | case 0xe: // AL |
| 1493 | break; | 1345 | temp = 1; |
| 1494 | case 0xe: /* AL */ | 1346 | break; |
| 1495 | temp = 1; | 1347 | case 0xf: |
| 1496 | break; | 1348 | temp = 1; |
| 1497 | case 0xf: | 1349 | break; |
| 1498 | // DEBUG_LOG(ARM11, "inst is %x\n"); | 1350 | } |
| 1499 | // DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter); | 1351 | return temp; |
| 1500 | // CITRA_IGNORE_EXIT(-1); | ||
| 1501 | temp = 1; | ||
| 1502 | break; | ||
| 1503 | } | ||
| 1504 | return temp; | ||
| 1505 | } | 1352 | } |
| 1506 | 1353 | ||
| 1507 | enum DECODE_STATUS { | 1354 | enum DECODE_STATUS { |
| 1508 | DECODE_SUCCESS, | 1355 | DECODE_SUCCESS, |
| 1509 | DECODE_FAILURE | 1356 | DECODE_FAILURE |
| 1510 | }; | 1357 | }; |
| 1511 | 1358 | ||
| 1512 | int decode_arm_instr(uint32_t instr, int32_t *idx); | 1359 | int decode_arm_instr(uint32_t instr, int32_t *idx); |
| 1513 | 1360 | ||
| 1514 | shtop_fp_t get_shtop(unsigned int inst) | 1361 | shtop_fp_t get_shtop(unsigned int inst) { |
| 1515 | { | 1362 | if (BIT(inst, 25)) { |
| 1516 | if (BIT(inst, 25)) { | 1363 | return DPO(Immediate); |
| 1517 | return DPO(Immediate); | 1364 | } else if (BITS(inst, 4, 11) == 0) { |
| 1518 | } else if (BITS(inst, 4, 11) == 0) { | 1365 | return DPO(Register); |
| 1519 | return DPO(Register); | 1366 | } else if (BITS(inst, 4, 6) == 0) { |
| 1520 | } else if (BITS(inst, 4, 6) == 0) { | 1367 | return DPO(LogicalShiftLeftByImmediate); |
| 1521 | return DPO(LogicalShiftLeftByImmediate); | 1368 | } else if (BITS(inst, 4, 7) == 1) { |
| 1522 | } else if (BITS(inst, 4, 7) == 1) { | 1369 | return DPO(LogicalShiftLeftByRegister); |
| 1523 | return DPO(LogicalShiftLeftByRegister); | 1370 | } else if (BITS(inst, 4, 6) == 2) { |
| 1524 | } else if (BITS(inst, 4, 6) == 2) { | 1371 | return DPO(LogicalShiftRightByImmediate); |
| 1525 | return DPO(LogicalShiftRightByImmediate); | 1372 | } else if (BITS(inst, 4, 7) == 3) { |
| 1526 | } else if (BITS(inst, 4, 7) == 3) { | 1373 | return DPO(LogicalShiftRightByRegister); |
| 1527 | return DPO(LogicalShiftRightByRegister); | 1374 | } else if (BITS(inst, 4, 6) == 4) { |
| 1528 | } else if (BITS(inst, 4, 6) == 4) { | 1375 | return DPO(ArithmeticShiftRightByImmediate); |
| 1529 | return DPO(ArithmeticShiftRightByImmediate); | 1376 | } else if (BITS(inst, 4, 7) == 5) { |
| 1530 | } else if (BITS(inst, 4, 7) == 5) { | 1377 | return DPO(ArithmeticShiftRightByRegister); |
| 1531 | return DPO(ArithmeticShiftRightByRegister); | 1378 | } else if (BITS(inst, 4, 6) == 6) { |
| 1532 | } else if (BITS(inst, 4, 6) == 6) { | 1379 | return DPO(RotateRightByImmediate); |
| 1533 | return DPO(RotateRightByImmediate); | 1380 | } else if (BITS(inst, 4, 7) == 7) { |
| 1534 | } else if (BITS(inst, 4, 7) == 7) { | 1381 | return DPO(RotateRightByRegister); |
| 1535 | return DPO(RotateRightByRegister); | 1382 | } |
| 1536 | } | 1383 | return nullptr; |
| 1537 | return NULL; | 1384 | } |
| 1538 | } | 1385 | |
| 1539 | 1386 | get_addr_fp_t get_calc_addr_op(unsigned int inst) { | |
| 1540 | get_addr_fp_t get_calc_addr_op(unsigned int inst) | 1387 | if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { |
| 1541 | { | 1388 | return LnSWoUB(ImmediateOffset); |
| 1542 | /* 1 */ | 1389 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { |
| 1543 | if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) { | 1390 | return LnSWoUB(RegisterOffset); |
| 1544 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1391 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { |
| 1545 | return LnSWoUB(ImmediateOffset); | 1392 | return LnSWoUB(ScaledRegisterOffset); |
| 1546 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { | 1393 | } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { |
| 1547 | // DEBUG_MSG; | 1394 | return LnSWoUB(ImmediatePreIndexed); |
| 1548 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1395 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { |
| 1549 | return LnSWoUB(RegisterOffset); | 1396 | return LnSWoUB(RegisterPreIndexed); |
| 1550 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { | 1397 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { |
| 1551 | // DEBUG_MSG; | 1398 | return LnSWoUB(ScaledRegisterPreIndexed); |
| 1552 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1399 | } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { |
| 1553 | return LnSWoUB(ScaledRegisterOffset); | 1400 | return LnSWoUB(ImmediatePostIndexed); |
| 1554 | } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) { | 1401 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { |
| 1555 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1402 | return LnSWoUB(RegisterPostIndexed); |
| 1556 | return LnSWoUB(ImmediatePreIndexed); | 1403 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { |
| 1557 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) { | 1404 | return LnSWoUB(ScaledRegisterPostIndexed); |
| 1558 | return LnSWoUB(RegisterPreIndexed); | 1405 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1559 | } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) { | 1406 | return MLnS(ImmediateOffset); |
| 1560 | return LnSWoUB(ScaledRegisterPreIndexed); | 1407 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1561 | } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) { | 1408 | return MLnS(RegisterOffset); |
| 1562 | return LnSWoUB(ImmediatePostIndexed); | 1409 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1563 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) { | 1410 | return MLnS(ImmediatePreIndexed); |
| 1564 | // DEBUG_MSG; | 1411 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1565 | return LnSWoUB(RegisterPostIndexed); | 1412 | return MLnS(RegisterPreIndexed); |
| 1566 | } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { | 1413 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1567 | return LnSWoUB(ScaledRegisterPostIndexed); | 1414 | return MLnS(ImmediatePostIndexed); |
| 1568 | // DEBUG_MSG; | 1415 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { |
| 1569 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | 1416 | return MLnS(RegisterPostIndexed); |
| 1570 | /* 2 */ | 1417 | } else if (BITS(inst, 23, 27) == 0x11) { |
| 1571 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | 1418 | return LdnStM(IncrementAfter); |
| 1572 | return MLnS(ImmediateOffset); | 1419 | } else if (BITS(inst, 23, 27) == 0x13) { |
| 1573 | // DEBUG_MSG; | 1420 | return LdnStM(IncrementBefore); |
| 1574 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | 1421 | } else if (BITS(inst, 23, 27) == 0x10) { |
| 1575 | // DEBUG_LOG(ARM11, "line is %d\n", __LINE__); | 1422 | return LdnStM(DecrementAfter); |
| 1576 | return MLnS(RegisterOffset); | 1423 | } else if (BITS(inst, 23, 27) == 0x12) { |
| 1577 | // DEBUG_MSG; | 1424 | return LdnStM(DecrementBefore); |
| 1578 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | 1425 | } |
| 1579 | // DEBUG_LOG(ARM11, "line is %d\n", __LINE__); | 1426 | return nullptr; |
| 1580 | return MLnS(ImmediatePreIndexed); | ||
| 1581 | // DEBUG_MSG; | ||
| 1582 | } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | ||
| 1583 | return MLnS(RegisterPreIndexed); | ||
| 1584 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | ||
| 1585 | // DEBUG_MSG; | ||
| 1586 | return MLnS(ImmediatePostIndexed); | ||
| 1587 | } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { | ||
| 1588 | //DEBUG_MSG; | ||
| 1589 | return MLnS(RegisterPostIndexed); | ||
| 1590 | } else if (BITS(inst, 23, 27) == 0x11) { | ||
| 1591 | /* 3 */ | ||
| 1592 | // DEBUG_MSG; | ||
| 1593 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1594 | return LdnStM(IncrementAfter); | ||
| 1595 | } else if (BITS(inst, 23, 27) == 0x13) { | ||
| 1596 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1597 | return LdnStM(IncrementBefore); | ||
| 1598 | // DEBUG_MSG; | ||
| 1599 | } else if (BITS(inst, 23, 27) == 0x10) { | ||
| 1600 | // DEBUG_MSG; | ||
| 1601 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1602 | return LdnStM(DecrementAfter); | ||
| 1603 | } else if (BITS(inst, 23, 27) == 0x12) { | ||
| 1604 | // DEBUG_MSG; | ||
| 1605 | // DEBUG_LOG(ARM11, "line is %d", __LINE__); | ||
| 1606 | return LdnStM(DecrementBefore); | ||
| 1607 | } | ||
| 1608 | #if 0 | ||
| 1609 | DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__); | ||
| 1610 | DEBUG_LOG(ARM11, "inst:%x\n", inst); | ||
| 1611 | CITRA_IGNORE_EXIT(-1); | ||
| 1612 | #endif | ||
| 1613 | return NULL; | ||
| 1614 | } | 1427 | } |
| 1615 | 1428 | ||
| 1616 | #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) | 1429 | #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) |
| 1617 | 1430 | ||
| 1618 | #define CHECK_RN (inst_cream->Rn == 15) | 1431 | #define CHECK_RN (inst_cream->Rn == 15) |
| 1619 | #define CHECK_RM (inst_cream->Rm == 15) | 1432 | #define CHECK_RM (inst_cream->Rm == 15) |
| 1620 | #define CHECK_RS (inst_cream->Rs == 15) | 1433 | #define CHECK_RS (inst_cream->Rs == 15) |
| 1621 | 1434 | ||
| 1435 | #define UNIMPLEMENTED_INSTRUCTION(mnemonic) \ | ||
| 1436 | LOG_ERROR(Core_ARM11, "unimplemented instruction: %s", mnemonic); \ | ||
| 1437 | CITRA_IGNORE_EXIT(-1); \ | ||
| 1438 | return nullptr; | ||
| 1622 | 1439 | ||
| 1623 | ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) | 1440 | ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) |
| 1624 | { | 1441 | { |
| 1625 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); | 1442 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); |
| 1626 | adc_inst *inst_cream = (adc_inst *)inst_base->component; | 1443 | adc_inst *inst_cream = (adc_inst *)inst_base->component; |
| 1627 | 1444 | ||
| 1628 | inst_base->cond = BITS(inst, 28, 31); | 1445 | inst_base->cond = BITS(inst, 28, 31); |
| 1629 | inst_base->idx = index; | 1446 | inst_base->idx = index; |
| 1630 | inst_base->br = NON_BRANCH; | 1447 | inst_base->br = NON_BRANCH; |
| 1631 | inst_base->load_r15 = 0; | 1448 | inst_base->load_r15 = 0; |
| 1632 | 1449 | ||
| 1633 | inst_cream->I = BIT(inst, 25); | 1450 | inst_cream->I = BIT(inst, 25); |
| 1634 | inst_cream->S = BIT(inst, 20); | 1451 | inst_cream->S = BIT(inst, 20); |
| 1635 | inst_cream->Rn = BITS(inst, 16, 19); | 1452 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1636 | inst_cream->Rd = BITS(inst, 12, 15); | 1453 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1637 | if (CHECK_RN) | 1454 | if (CHECK_RN) |
| 1638 | inst_base->load_r15 = 1; | 1455 | inst_base->load_r15 = 1; |
| 1639 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1456 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1640 | inst_cream->shtop_func = get_shtop(inst); | 1457 | inst_cream->shtop_func = get_shtop(inst); |
| 1641 | if (inst_cream->Rd == 15) { | 1458 | if (inst_cream->Rd == 15) { |
| 1642 | inst_base->br = INDIRECT_BRANCH; | 1459 | inst_base->br = INDIRECT_BRANCH; |
| 1643 | } | 1460 | } |
| 1644 | return inst_base; | 1461 | return inst_base; |
| 1645 | } | 1462 | } |
| 1646 | ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) | 1463 | ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) |
| 1647 | { | 1464 | { |
| 1648 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); | 1465 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); |
| 1649 | add_inst *inst_cream = (add_inst *)inst_base->component; | 1466 | add_inst *inst_cream = (add_inst *)inst_base->component; |
| 1650 | 1467 | ||
| 1651 | inst_base->cond = BITS(inst, 28, 31); | 1468 | inst_base->cond = BITS(inst, 28, 31); |
| 1652 | inst_base->idx = index; | 1469 | inst_base->idx = index; |
| 1653 | inst_base->br = NON_BRANCH; | 1470 | inst_base->br = NON_BRANCH; |
| 1654 | inst_base->load_r15 = 0; | 1471 | inst_base->load_r15 = 0; |
| 1655 | 1472 | ||
| 1656 | inst_cream->I = BIT(inst, 25); | 1473 | inst_cream->I = BIT(inst, 25); |
| 1657 | inst_cream->S = BIT(inst, 20); | 1474 | inst_cream->S = BIT(inst, 20); |
| 1658 | inst_cream->Rn = BITS(inst, 16, 19); | 1475 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1659 | inst_cream->Rd = BITS(inst, 12, 15); | 1476 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1660 | if (CHECK_RN) | 1477 | if (CHECK_RN) |
| 1661 | inst_base->load_r15 = 1; | 1478 | inst_base->load_r15 = 1; |
| 1662 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1479 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1663 | inst_cream->shtop_func = get_shtop(inst); | 1480 | inst_cream->shtop_func = get_shtop(inst); |
| 1664 | if (inst_cream->Rd == 15) { | 1481 | if (inst_cream->Rd == 15) { |
| 1665 | inst_base->br = INDIRECT_BRANCH; | 1482 | inst_base->br = INDIRECT_BRANCH; |
| 1666 | } | 1483 | } |
| 1667 | return inst_base; | 1484 | return inst_base; |
| 1668 | } | 1485 | } |
| 1669 | ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) | 1486 | ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) |
| 1670 | { | 1487 | { |
| 1671 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); | 1488 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); |
| 1672 | and_inst *inst_cream = (and_inst *)inst_base->component; | 1489 | and_inst *inst_cream = (and_inst *)inst_base->component; |
| 1673 | 1490 | ||
| 1674 | inst_base->cond = BITS(inst, 28, 31); | 1491 | inst_base->cond = BITS(inst, 28, 31); |
| 1675 | inst_base->idx = index; | 1492 | inst_base->idx = index; |
| 1676 | inst_base->br = NON_BRANCH; | 1493 | inst_base->br = NON_BRANCH; |
| 1677 | inst_base->load_r15 = 0; | 1494 | inst_base->load_r15 = 0; |
| 1678 | 1495 | ||
| 1679 | inst_cream->I = BIT(inst, 25); | 1496 | inst_cream->I = BIT(inst, 25); |
| 1680 | inst_cream->S = BIT(inst, 20); | 1497 | inst_cream->S = BIT(inst, 20); |
| 1681 | inst_cream->Rn = BITS(inst, 16, 19); | 1498 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1682 | inst_cream->Rd = BITS(inst, 12, 15); | 1499 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1683 | if (CHECK_RN) | 1500 | if (CHECK_RN) |
| 1684 | inst_base->load_r15 = 1; | 1501 | inst_base->load_r15 = 1; |
| 1685 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1502 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1686 | inst_cream->shtop_func = get_shtop(inst); | 1503 | inst_cream->shtop_func = get_shtop(inst); |
| 1687 | if (inst_cream->Rd == 15) | 1504 | if (inst_cream->Rd == 15) |
| 1688 | inst_base->br = INDIRECT_BRANCH; | 1505 | inst_base->br = INDIRECT_BRANCH; |
| 1689 | return inst_base; | 1506 | return inst_base; |
| 1690 | } | 1507 | } |
| 1691 | ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) | 1508 | ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) |
| 1692 | { | 1509 | { |
| 1693 | #define POSBRANCH ((inst & 0x7fffff) << 2) | 1510 | #define POSBRANCH ((inst & 0x7fffff) << 2) |
| 1694 | #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) | 1511 | #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) |
| 1695 | 1512 | ||
| 1696 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); | 1513 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); |
| 1697 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; | 1514 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; |
| 1698 | 1515 | ||
| 1699 | inst_base->cond = BITS(inst, 28, 31); | 1516 | inst_base->cond = BITS(inst, 28, 31); |
| 1700 | inst_base->idx = index; | 1517 | inst_base->idx = index; |
| 1701 | inst_base->br = DIRECT_BRANCH; | 1518 | inst_base->br = DIRECT_BRANCH; |
| 1702 | 1519 | ||
| 1703 | if (BIT(inst, 24)) | 1520 | if (BIT(inst, 24)) |
| 1704 | inst_base->br = CALL; | 1521 | inst_base->br = CALL; |
| 1705 | if (BITS(inst, 28, 31) <= 0xe) | 1522 | if (BITS(inst, 28, 31) <= 0xe) |
| 1706 | inst_base->br |= COND; | 1523 | inst_base->br |= COND; |
| 1707 | 1524 | ||
| 1708 | inst_cream->L = BIT(inst, 24); | 1525 | inst_cream->L = BIT(inst, 24); |
| 1709 | inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; | 1526 | inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; |
| 1710 | 1527 | ||
| 1711 | return inst_base; | 1528 | return inst_base; |
| 1712 | } | 1529 | } |
| 1713 | ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) | 1530 | ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) |
| 1714 | { | 1531 | { |
| 1715 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); | 1532 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); |
| 1716 | bic_inst *inst_cream = (bic_inst *)inst_base->component; | 1533 | bic_inst *inst_cream = (bic_inst *)inst_base->component; |
| 1717 | 1534 | ||
| 1718 | inst_base->cond = BITS(inst, 28, 31); | 1535 | inst_base->cond = BITS(inst, 28, 31); |
| 1719 | inst_base->idx = index; | 1536 | inst_base->idx = index; |
| 1720 | inst_base->br = NON_BRANCH; | 1537 | inst_base->br = NON_BRANCH; |
| 1721 | inst_base->load_r15 = 0; | 1538 | inst_base->load_r15 = 0; |
| 1722 | 1539 | ||
| 1723 | inst_cream->I = BIT(inst, 25); | 1540 | inst_cream->I = BIT(inst, 25); |
| 1724 | inst_cream->S = BIT(inst, 20); | 1541 | inst_cream->S = BIT(inst, 20); |
| 1725 | inst_cream->Rn = BITS(inst, 16, 19); | 1542 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1726 | inst_cream->Rd = BITS(inst, 12, 15); | 1543 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1727 | if (CHECK_RN) | 1544 | if (CHECK_RN) |
| 1728 | inst_base->load_r15 = 1; | 1545 | inst_base->load_r15 = 1; |
| 1729 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1546 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1730 | inst_cream->shtop_func = get_shtop(inst); | 1547 | inst_cream->shtop_func = get_shtop(inst); |
| 1731 | 1548 | ||
| 1732 | if (inst_cream->Rd == 15) | 1549 | if (inst_cream->Rd == 15) |
| 1733 | inst_base->br = INDIRECT_BRANCH; | 1550 | inst_base->br = INDIRECT_BRANCH; |
| 1734 | return inst_base; | 1551 | return inst_base; |
| 1735 | } | 1552 | } |
| 1736 | 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;} | 1553 | ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BKPT"); } |
| 1737 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) | 1554 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) |
| 1738 | { | 1555 | { |
| 1739 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); | 1556 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); |
| 1740 | blx_inst *inst_cream = (blx_inst *)inst_base->component; | 1557 | blx_inst *inst_cream = (blx_inst *)inst_base->component; |
| 1741 | 1558 | ||
| 1742 | inst_base->cond = BITS(inst, 28, 31); | 1559 | inst_base->cond = BITS(inst, 28, 31); |
| 1743 | inst_base->idx = index; | 1560 | inst_base->idx = index; |
| 1744 | inst_base->br = INDIRECT_BRANCH; | 1561 | inst_base->br = INDIRECT_BRANCH; |
| 1745 | 1562 | ||
| 1746 | inst_cream->inst = inst; | 1563 | inst_cream->inst = inst; |
| 1747 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { | 1564 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { |
| 1748 | inst_cream->val.Rm = BITS(inst, 0, 3); | 1565 | inst_cream->val.Rm = BITS(inst, 0, 3); |
| 1749 | } else { | 1566 | } else { |
| 1750 | inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); | 1567 | inst_cream->val.signed_immed_24 = BITS(inst, 0, 23); |
| 1751 | //DEBUG_LOG(ARM11, " blx inst is %x\n", inst); | 1568 | } |
| 1752 | //CITRA_IGNORE_EXIT(-1); | ||
| 1753 | // DEBUG_MSG; | ||
| 1754 | } | ||
| 1755 | 1569 | ||
| 1756 | return inst_base; | 1570 | return inst_base; |
| 1757 | } | 1571 | } |
| 1758 | ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) | 1572 | ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) |
| 1759 | { | 1573 | { |
| 1760 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); | 1574 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); |
| 1761 | bx_inst *inst_cream = (bx_inst *)inst_base->component; | 1575 | bx_inst *inst_cream = (bx_inst *)inst_base->component; |
| 1762 | 1576 | ||
| 1763 | inst_base->cond = BITS(inst, 28, 31); | 1577 | inst_base->cond = BITS(inst, 28, 31); |
| 1764 | inst_base->idx = index; | 1578 | inst_base->idx = index; |
| 1765 | inst_base->br = INDIRECT_BRANCH; | 1579 | inst_base->br = INDIRECT_BRANCH; |
| 1766 | 1580 | ||
| 1767 | inst_cream->Rm = BITS(inst, 0, 3); | 1581 | inst_cream->Rm = BITS(inst, 0, 3); |
| 1768 | 1582 | ||
| 1769 | return inst_base; | 1583 | return inst_base; |
| 1770 | } | 1584 | } |
| 1771 | 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;} | 1585 | ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } |
| 1772 | ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ | 1586 | ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ |
| 1773 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); | 1587 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); |
| 1774 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; | 1588 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; |
| 1775 | inst_base->cond = BITS(inst, 28, 31); | 1589 | inst_base->cond = BITS(inst, 28, 31); |
| 1776 | inst_base->idx = index; | 1590 | inst_base->idx = index; |
| 1777 | inst_base->br = NON_BRANCH; | 1591 | inst_base->br = NON_BRANCH; |
| 1778 | inst_base->load_r15 = 0; | 1592 | inst_base->load_r15 = 0; |
| 1779 | 1593 | ||
| 1780 | inst_cream->CRm = BITS(inst, 0, 3); | 1594 | inst_cream->CRm = BITS(inst, 0, 3); |
| 1781 | inst_cream->CRd = BITS(inst, 12, 15); | 1595 | inst_cream->CRd = BITS(inst, 12, 15); |
| 1782 | inst_cream->CRn = BITS(inst, 16, 19); | 1596 | inst_cream->CRn = BITS(inst, 16, 19); |
| 1783 | inst_cream->cp_num = BITS(inst, 8, 11); | 1597 | inst_cream->cp_num = BITS(inst, 8, 11); |
| 1784 | inst_cream->opcode_2 = BITS(inst, 5, 7); | 1598 | inst_cream->opcode_2 = BITS(inst, 5, 7); |
| 1785 | inst_cream->opcode_1 = BITS(inst, 20, 23); | 1599 | inst_cream->opcode_1 = BITS(inst, 20, 23); |
| 1786 | inst_cream->inst = inst; | 1600 | inst_cream->inst = inst; |
| 1787 | 1601 | ||
| 1788 | DEBUG_LOG(ARM11, "in func %s inst %x index %x\n", __FUNCTION__, inst, index); | 1602 | LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index); |
| 1789 | return inst_base; | 1603 | return inst_base; |
| 1790 | } | 1604 | } |
| 1791 | ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) | 1605 | ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) |
| 1792 | { | 1606 | { |
| 1793 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); | 1607 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); |
| 1794 | inst_base->cond = BITS(inst, 28, 31); | 1608 | inst_base->cond = BITS(inst, 28, 31); |
| 1795 | inst_base->idx = index; | 1609 | inst_base->idx = index; |
| 1796 | inst_base->br = NON_BRANCH; | 1610 | inst_base->br = NON_BRANCH; |
| 1797 | 1611 | ||
| 1798 | return inst_base; | 1612 | return inst_base; |
| 1799 | } | 1613 | } |
| 1800 | ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) | 1614 | ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) |
| 1801 | { | 1615 | { |
| 1802 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); | 1616 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); |
| 1803 | clz_inst *inst_cream = (clz_inst *)inst_base->component; | 1617 | clz_inst *inst_cream = (clz_inst *)inst_base->component; |
| 1804 | 1618 | ||
| 1805 | inst_base->cond = BITS(inst, 28, 31); | 1619 | inst_base->cond = BITS(inst, 28, 31); |
| 1806 | inst_base->idx = index; | 1620 | inst_base->idx = index; |
| 1807 | inst_base->br = NON_BRANCH; | 1621 | inst_base->br = NON_BRANCH; |
| 1808 | inst_base->load_r15 = 0; | 1622 | inst_base->load_r15 = 0; |
| 1809 | 1623 | ||
| 1810 | inst_cream->Rm = BITS(inst, 0, 3); | 1624 | inst_cream->Rm = BITS(inst, 0, 3); |
| 1811 | inst_cream->Rd = BITS(inst, 12, 15); | 1625 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1812 | if (CHECK_RM) | 1626 | if (CHECK_RM) |
| 1813 | inst_base->load_r15 = 1; | 1627 | inst_base->load_r15 = 1; |
| 1814 | 1628 | ||
| 1815 | return inst_base; | 1629 | return inst_base; |
| 1816 | } | 1630 | } |
| 1817 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) | 1631 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) |
| 1818 | { | 1632 | { |
| 1819 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); | 1633 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); |
| 1820 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; | 1634 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; |
| 1821 | 1635 | ||
| 1822 | inst_base->cond = BITS(inst, 28, 31); | 1636 | inst_base->cond = BITS(inst, 28, 31); |
| 1823 | inst_base->idx = index; | 1637 | inst_base->idx = index; |
| 1824 | inst_base->br = NON_BRANCH; | 1638 | inst_base->br = NON_BRANCH; |
| 1825 | inst_base->load_r15 = 0; | 1639 | inst_base->load_r15 = 0; |
| 1826 | 1640 | ||
| 1827 | inst_cream->I = BIT(inst, 25); | 1641 | inst_cream->I = BIT(inst, 25); |
| 1828 | //inst_cream->S = BIT(inst, 20); | 1642 | //inst_cream->S = BIT(inst, 20); |
| 1829 | inst_cream->Rn = BITS(inst, 16, 19); | 1643 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1830 | //inst_cream->Rd = BITS(inst, 12, 15); | 1644 | //inst_cream->Rd = BITS(inst, 12, 15); |
| 1831 | if (CHECK_RN) | 1645 | if (CHECK_RN) |
| 1832 | inst_base->load_r15 = 1; | 1646 | inst_base->load_r15 = 1; |
| 1833 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1647 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1834 | inst_cream->shtop_func = get_shtop(inst); | 1648 | inst_cream->shtop_func = get_shtop(inst); |
| 1835 | return inst_base; | 1649 | return inst_base; |
| 1836 | } | 1650 | } |
| 1837 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) | 1651 | ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) |
| 1838 | { | 1652 | { |
| 1839 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); | 1653 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); |
| 1840 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | 1654 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; |
| 1841 | 1655 | ||
| 1842 | inst_base->cond = BITS(inst, 28, 31); | 1656 | inst_base->cond = BITS(inst, 28, 31); |
| 1843 | inst_base->idx = index; | 1657 | inst_base->idx = index; |
| 1844 | inst_base->br = NON_BRANCH; | 1658 | inst_base->br = NON_BRANCH; |
| 1845 | inst_base->load_r15 = 0; | 1659 | inst_base->load_r15 = 0; |
| 1846 | 1660 | ||
| 1847 | inst_cream->I = BIT(inst, 25); | 1661 | inst_cream->I = BIT(inst, 25); |
| 1848 | inst_cream->Rn = BITS(inst, 16, 19); | 1662 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1849 | if (CHECK_RN) | 1663 | if (CHECK_RN) |
| 1850 | inst_base->load_r15 = 1; | 1664 | inst_base->load_r15 = 1; |
| 1851 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1665 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1852 | inst_cream->shtop_func = get_shtop(inst); | 1666 | inst_cream->shtop_func = get_shtop(inst); |
| 1853 | return inst_base; | 1667 | return inst_base; |
| 1854 | } | 1668 | } |
| 1855 | ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) | 1669 | ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) |
| 1856 | { | 1670 | { |
| 1857 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); | 1671 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); |
| 1858 | cps_inst *inst_cream = (cps_inst *)inst_base->component; | 1672 | cps_inst *inst_cream = (cps_inst *)inst_base->component; |
| 1859 | 1673 | ||
| 1860 | inst_base->cond = BITS(inst, 28, 31); | 1674 | inst_base->cond = BITS(inst, 28, 31); |
| 1861 | inst_base->idx = index; | 1675 | inst_base->idx = index; |
| 1862 | inst_base->br = NON_BRANCH; | 1676 | inst_base->br = NON_BRANCH; |
| 1863 | 1677 | ||
| 1864 | inst_cream->imod0 = BIT(inst, 18); | 1678 | inst_cream->imod0 = BIT(inst, 18); |
| 1865 | inst_cream->imod1 = BIT(inst, 19); | 1679 | inst_cream->imod1 = BIT(inst, 19); |
| 1866 | inst_cream->mmod = BIT(inst, 17); | 1680 | inst_cream->mmod = BIT(inst, 17); |
| 1867 | inst_cream->A = BIT(inst, 8); | 1681 | inst_cream->A = BIT(inst, 8); |
| 1868 | inst_cream->I = BIT(inst, 7); | 1682 | inst_cream->I = BIT(inst, 7); |
| 1869 | inst_cream->F = BIT(inst, 6); | 1683 | inst_cream->F = BIT(inst, 6); |
| 1870 | inst_cream->mode = BITS(inst, 0, 4); | 1684 | inst_cream->mode = BITS(inst, 0, 4); |
| 1871 | 1685 | ||
| 1872 | return inst_base; | 1686 | return inst_base; |
| 1873 | } | 1687 | } |
| 1874 | ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) | 1688 | ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) |
| 1875 | { | 1689 | { |
| 1876 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); | 1690 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); |
| 1877 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 1691 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 1878 | 1692 | ||
| 1879 | inst_base->cond = BITS(inst, 28, 31); | 1693 | inst_base->cond = BITS(inst, 28, 31); |
| 1880 | inst_base->idx = index; | 1694 | inst_base->idx = index; |
| 1881 | inst_base->br = NON_BRANCH; | 1695 | inst_base->br = NON_BRANCH; |
| 1882 | 1696 | ||
| 1883 | inst_cream->I = BIT(inst, 25); | 1697 | inst_cream->I = BIT(inst, 25); |
| 1884 | inst_cream->S = BIT(inst, 20); | 1698 | inst_cream->S = BIT(inst, 20); |
| 1885 | inst_cream->Rd = BITS(inst, 12, 15); | 1699 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1886 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1700 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1887 | inst_cream->shtop_func = get_shtop(inst); | 1701 | inst_cream->shtop_func = get_shtop(inst); |
| 1888 | 1702 | ||
| 1889 | if (inst_cream->Rd == 15) { | 1703 | if (inst_cream->Rd == 15) { |
| 1890 | inst_base->br = INDIRECT_BRANCH; | 1704 | inst_base->br = INDIRECT_BRANCH; |
| 1891 | } | 1705 | } |
| 1892 | return inst_base; | 1706 | return inst_base; |
| 1893 | } | 1707 | } |
| 1894 | ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) | 1708 | ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) |
| 1895 | { | 1709 | { |
| 1896 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); | 1710 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); |
| 1897 | eor_inst *inst_cream = (eor_inst *)inst_base->component; | 1711 | eor_inst *inst_cream = (eor_inst *)inst_base->component; |
| 1898 | 1712 | ||
| 1899 | inst_base->cond = BITS(inst, 28, 31); | 1713 | inst_base->cond = BITS(inst, 28, 31); |
| 1900 | inst_base->idx = index; | 1714 | inst_base->idx = index; |
| 1901 | inst_base->br = NON_BRANCH; | 1715 | inst_base->br = NON_BRANCH; |
| 1902 | inst_base->load_r15 = 0; | 1716 | inst_base->load_r15 = 0; |
| 1903 | 1717 | ||
| 1904 | inst_cream->I = BIT(inst, 25); | 1718 | inst_cream->I = BIT(inst, 25); |
| 1905 | inst_cream->S = BIT(inst, 20); | 1719 | inst_cream->S = BIT(inst, 20); |
| 1906 | inst_cream->Rn = BITS(inst, 16, 19); | 1720 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1907 | inst_cream->Rd = BITS(inst, 12, 15); | 1721 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1908 | if (CHECK_RN) | 1722 | if (CHECK_RN) |
| 1909 | inst_base->load_r15 = 1; | 1723 | inst_base->load_r15 = 1; |
| 1910 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 1724 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 1911 | inst_cream->shtop_func = get_shtop(inst); | 1725 | inst_cream->shtop_func = get_shtop(inst); |
| 1912 | if (inst_cream->Rd == 15) { | 1726 | if (inst_cream->Rd == 15) { |
| 1913 | inst_base->br = INDIRECT_BRANCH; | 1727 | inst_base->br = INDIRECT_BRANCH; |
| 1914 | } | 1728 | } |
| 1915 | return inst_base; | 1729 | return inst_base; |
| 1916 | } | 1730 | } |
| 1917 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) | 1731 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) |
| 1918 | { | 1732 | { |
| 1919 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); | 1733 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); |
| 1920 | inst_base->cond = BITS(inst, 28, 31); | 1734 | inst_base->cond = BITS(inst, 28, 31); |
| 1921 | inst_base->idx = index; | 1735 | inst_base->idx = index; |
| 1922 | inst_base->br = NON_BRANCH; | 1736 | inst_base->br = NON_BRANCH; |
| 1923 | 1737 | ||
| 1924 | return inst_base; | 1738 | return inst_base; |
| 1925 | } | 1739 | } |
| 1926 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) | 1740 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) |
| 1927 | { | 1741 | { |
| 1928 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1742 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 1929 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1743 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 1930 | 1744 | ||
| 1931 | inst_base->cond = BITS(inst, 28, 31); | 1745 | inst_base->cond = BITS(inst, 28, 31); |
| 1932 | inst_base->idx = index; | 1746 | inst_base->idx = index; |
| 1933 | inst_base->br = NON_BRANCH; | 1747 | inst_base->br = NON_BRANCH; |
| 1934 | 1748 | ||
| 1935 | inst_cream->inst = inst; | 1749 | inst_cream->inst = inst; |
| 1936 | inst_cream->get_addr = get_calc_addr_op(inst); | 1750 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 1937 | 1751 | ||
| 1938 | if (BIT(inst, 15)) { | 1752 | if (BIT(inst, 15)) { |
| 1939 | inst_base->br = INDIRECT_BRANCH; | 1753 | inst_base->br = INDIRECT_BRANCH; |
| 1940 | } | 1754 | } |
| 1941 | return inst_base; | 1755 | return inst_base; |
| 1942 | } | 1756 | } |
| 1943 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) | 1757 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) |
| 1944 | { | 1758 | { |
| 1945 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); | 1759 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); |
| 1946 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | 1760 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; |
| 1947 | 1761 | ||
| 1948 | inst_base->cond = BITS(inst, 28, 31); | 1762 | inst_base->cond = BITS(inst, 28, 31); |
| 1949 | inst_base->idx = index; | 1763 | inst_base->idx = index; |
| 1950 | inst_base->br = NON_BRANCH; | 1764 | inst_base->br = NON_BRANCH; |
| 1951 | inst_base->load_r15 = 0; | 1765 | inst_base->load_r15 = 0; |
| 1952 | 1766 | ||
| 1953 | inst_cream->Rd = BITS(inst, 12, 15); | 1767 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1954 | inst_cream->Rm = BITS(inst, 0, 3); | 1768 | inst_cream->Rm = BITS(inst, 0, 3); |
| 1955 | inst_cream->rotate = BITS(inst, 10, 11); | 1769 | inst_cream->rotate = BITS(inst, 10, 11); |
| 1956 | if (CHECK_RM) | 1770 | if (CHECK_RM) |
| 1957 | inst_base->load_r15 = 1; | 1771 | inst_base->load_r15 = 1; |
| 1958 | 1772 | ||
| 1959 | return inst_base; | 1773 | return inst_base; |
| 1960 | } | 1774 | } |
| 1961 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) | 1775 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) |
| 1962 | { | 1776 | { |
| 1963 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1777 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 1964 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1778 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 1965 | 1779 | ||
| 1966 | inst_base->cond = BITS(inst, 28, 31); | 1780 | inst_base->cond = BITS(inst, 28, 31); |
| 1967 | inst_base->idx = index; | 1781 | inst_base->idx = index; |
| 1968 | inst_base->br = NON_BRANCH; | 1782 | inst_base->br = NON_BRANCH; |
| 1969 | inst_base->load_r15 = 0; | 1783 | inst_base->load_r15 = 0; |
| 1970 | 1784 | ||
| 1971 | inst_cream->inst = inst; | 1785 | inst_cream->inst = inst; |
| 1972 | inst_cream->get_addr = get_calc_addr_op(inst); | 1786 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 1973 | 1787 | ||
| 1974 | if (BITS(inst, 12, 15) == 15) { | 1788 | if (BITS(inst, 12, 15) == 15) { |
| 1975 | inst_base->br = INDIRECT_BRANCH; | 1789 | inst_base->br = INDIRECT_BRANCH; |
| 1976 | } | 1790 | } |
| 1977 | return inst_base; | 1791 | return inst_base; |
| 1978 | } | 1792 | } |
| 1979 | 1793 | ||
| 1980 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) | 1794 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) |
| 1981 | { | 1795 | { |
| 1982 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1796 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 1983 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1797 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 1984 | 1798 | ||
| 1985 | inst_base->cond = BITS(inst, 28, 31); | 1799 | inst_base->cond = BITS(inst, 28, 31); |
| 1986 | inst_base->idx = index; | 1800 | inst_base->idx = index; |
| 1987 | inst_base->br = NON_BRANCH; | 1801 | inst_base->br = NON_BRANCH; |
| 1988 | inst_base->load_r15 = 0; | 1802 | inst_base->load_r15 = 0; |
| 1989 | 1803 | ||
| 1990 | inst_cream->inst = inst; | 1804 | inst_cream->inst = inst; |
| 1991 | inst_cream->get_addr = get_calc_addr_op(inst); | 1805 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 1992 | 1806 | ||
| 1993 | if (BITS(inst, 12, 15) == 15) { | 1807 | if (BITS(inst, 12, 15) == 15) { |
| 1994 | inst_base->br = INDIRECT_BRANCH; | 1808 | inst_base->br = INDIRECT_BRANCH; |
| 1995 | } | 1809 | } |
| 1996 | return inst_base; | 1810 | return inst_base; |
| 1997 | } | 1811 | } |
| 1998 | 1812 | ||
| 1999 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) | 1813 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) |
| 2000 | { | 1814 | { |
| 2001 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); | 1815 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); |
| 2002 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; | 1816 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; |
| 2003 | 1817 | ||
| 2004 | inst_base->cond = BITS(inst, 28, 31); | 1818 | inst_base->cond = BITS(inst, 28, 31); |
| 2005 | inst_base->idx = index; | 1819 | inst_base->idx = index; |
| 2006 | inst_base->br = NON_BRANCH; | 1820 | inst_base->br = NON_BRANCH; |
| 2007 | inst_base->load_r15 = 0; | 1821 | inst_base->load_r15 = 0; |
| 2008 | 1822 | ||
| 2009 | inst_cream->Rd = BITS(inst, 12, 15); | 1823 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2010 | inst_cream->rotate = BITS(inst, 10, 11); | 1824 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2011 | inst_cream->Rm = BITS(inst, 0, 3); | 1825 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2012 | if (CHECK_RM) | 1826 | if (CHECK_RM) |
| 2013 | inst_base->load_r15 = 1; | 1827 | inst_base->load_r15 = 1; |
| 2014 | 1828 | ||
| 2015 | return inst_base; | 1829 | return inst_base; |
| 2016 | } | 1830 | } |
| 2017 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) | 1831 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) |
| 2018 | { | 1832 | { |
| 2019 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); | 1833 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); |
| 2020 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; | 1834 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; |
| 2021 | 1835 | ||
| 2022 | inst_base->cond = BITS(inst, 28, 31); | 1836 | inst_base->cond = BITS(inst, 28, 31); |
| 2023 | inst_base->idx = index; | 1837 | inst_base->idx = index; |
| 2024 | inst_base->br = NON_BRANCH; | 1838 | inst_base->br = NON_BRANCH; |
| 2025 | inst_base->load_r15 = 0; | 1839 | inst_base->load_r15 = 0; |
| 2026 | 1840 | ||
| 2027 | inst_cream->Rn = BITS(inst, 16, 19); | 1841 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2028 | inst_cream->Rd = BITS(inst, 12, 15); | 1842 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2029 | inst_cream->rotate = BITS(inst, 10, 11); | 1843 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2030 | inst_cream->Rm = BITS(inst, 0, 3); | 1844 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2031 | if (CHECK_RM || CHECK_RN) | 1845 | if (CHECK_RM || CHECK_RN) |
| 2032 | inst_base->load_r15 = 1; | 1846 | inst_base->load_r15 = 1; |
| 2033 | 1847 | ||
| 2034 | return inst_base; | 1848 | return inst_base; |
| 2035 | } | 1849 | } |
| 2036 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) | 1850 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) |
| 2037 | { | 1851 | { |
| 2038 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1852 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2039 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1853 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2040 | 1854 | ||
| 2041 | inst_base->cond = BITS(inst, 28, 31); | 1855 | inst_base->cond = BITS(inst, 28, 31); |
| 2042 | inst_base->idx = index; | 1856 | inst_base->idx = index; |
| 2043 | inst_base->br = NON_BRANCH; | 1857 | inst_base->br = NON_BRANCH; |
| 2044 | 1858 | ||
| 2045 | inst_cream->inst = inst; | 1859 | inst_cream->inst = inst; |
| 2046 | inst_cream->get_addr = get_calc_addr_op(inst); | 1860 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2047 | 1861 | ||
| 2048 | if (BITS(inst, 12, 15) == 15) { | 1862 | if (BITS(inst, 12, 15) == 15) { |
| 2049 | inst_base->br = INDIRECT_BRANCH; | 1863 | inst_base->br = INDIRECT_BRANCH; |
| 2050 | } | 1864 | } |
| 2051 | return inst_base; | 1865 | return inst_base; |
| 2052 | } | 1866 | } |
| 2053 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) | 1867 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) |
| 2054 | { | 1868 | { |
| 2055 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1869 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2056 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1870 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2057 | 1871 | ||
| 2058 | inst_base->cond = BITS(inst, 28, 31); | 1872 | inst_base->cond = BITS(inst, 28, 31); |
| 2059 | inst_base->idx = index; | 1873 | inst_base->idx = index; |
| 2060 | inst_base->br = NON_BRANCH; | 1874 | inst_base->br = NON_BRANCH; |
| 2061 | 1875 | ||
| 2062 | inst_cream->inst = inst; | 1876 | inst_cream->inst = inst; |
| 2063 | if (I_BIT == 0) { | 1877 | if (I_BIT == 0) { |
| 2064 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 1878 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2065 | } else { | 1879 | } else { |
| 2066 | DEBUG_MSG; | 1880 | DEBUG_MSG; |
| 2067 | } | 1881 | } |
| 2068 | #if 0 | 1882 | #if 0 |
| 2069 | inst_cream->get_addr = get_calc_addr_op(inst); | 1883 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2070 | if(inst == 0x54f13001) { | 1884 | if(inst == 0x54f13001) { |
| 2071 | DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); | 1885 | DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); |
| 2072 | } | 1886 | } |
| 2073 | #endif | 1887 | #endif |
| 2074 | 1888 | ||
| 2075 | if (BITS(inst, 12, 15) == 15) { | 1889 | if (BITS(inst, 12, 15) == 15) { |
| 2076 | inst_base->br = INDIRECT_BRANCH; | 1890 | inst_base->br = INDIRECT_BRANCH; |
| 2077 | } | 1891 | } |
| 2078 | return inst_base; | 1892 | return inst_base; |
| 2079 | } | 1893 | } |
| 2080 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) | 1894 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) |
| 2081 | { | 1895 | { |
| 2082 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1896 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2083 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1897 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2084 | 1898 | ||
| 2085 | inst_base->cond = BITS(inst, 28, 31); | 1899 | inst_base->cond = BITS(inst, 28, 31); |
| 2086 | inst_base->idx = index; | 1900 | inst_base->idx = index; |
| 2087 | inst_base->br = NON_BRANCH; | 1901 | inst_base->br = NON_BRANCH; |
| 2088 | 1902 | ||
| 2089 | inst_cream->inst = inst; | 1903 | inst_cream->inst = inst; |
| 2090 | inst_cream->get_addr = get_calc_addr_op(inst); | 1904 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2091 | 1905 | ||
| 2092 | return inst_base; | 1906 | return inst_base; |
| 2093 | } | 1907 | } |
| 2094 | 1908 | ||
| 2095 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) | 1909 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) |
| 2096 | { | 1910 | { |
| 2097 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1911 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2098 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1912 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2099 | 1913 | ||
| 2100 | inst_base->cond = BITS(inst, 28, 31); | 1914 | inst_base->cond = BITS(inst, 28, 31); |
| 2101 | inst_base->idx = index; | 1915 | inst_base->idx = index; |
| 2102 | inst_base->br = NON_BRANCH; | 1916 | inst_base->br = NON_BRANCH; |
| 2103 | 1917 | ||
| 2104 | inst_cream->inst = inst; | 1918 | inst_cream->inst = inst; |
| 2105 | //inst_cream->get_addr = get_calc_addr_op(inst); | 1919 | //inst_cream->get_addr = get_calc_addr_op(inst); |
| 2106 | 1920 | ||
| 2107 | if (BITS(inst, 12, 15) == 15) { | 1921 | if (BITS(inst, 12, 15) == 15) { |
| 2108 | inst_base->br = INDIRECT_BRANCH; | 1922 | inst_base->br = INDIRECT_BRANCH; |
| 2109 | } | 1923 | } |
| 2110 | return inst_base; | 1924 | return inst_base; |
| 2111 | } | 1925 | } |
| 2112 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) | 1926 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) |
| 2113 | { | 1927 | { |
| 2114 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1928 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2115 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1929 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2116 | 1930 | ||
| 2117 | inst_base->cond = BITS(inst, 28, 31); | 1931 | inst_base->cond = BITS(inst, 28, 31); |
| 2118 | inst_base->idx = index; | 1932 | inst_base->idx = index; |
| 2119 | inst_base->br = NON_BRANCH; | 1933 | inst_base->br = NON_BRANCH; |
| 2120 | 1934 | ||
| 2121 | inst_cream->inst = inst; | 1935 | inst_cream->inst = inst; |
| 2122 | inst_cream->get_addr = get_calc_addr_op(inst); | 1936 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2123 | 1937 | ||
| 2124 | if (BITS(inst, 12, 15) == 15) { | 1938 | if (BITS(inst, 12, 15) == 15) { |
| 2125 | inst_base->br = INDIRECT_BRANCH; | 1939 | inst_base->br = INDIRECT_BRANCH; |
| 2126 | } | 1940 | } |
| 2127 | return inst_base; | 1941 | return inst_base; |
| 2128 | } | 1942 | } |
| 2129 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) | 1943 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) |
| 2130 | { | 1944 | { |
| 2131 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1945 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2132 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1946 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2133 | 1947 | ||
| 2134 | inst_base->cond = BITS(inst, 28, 31); | 1948 | inst_base->cond = BITS(inst, 28, 31); |
| 2135 | inst_base->idx = index; | 1949 | inst_base->idx = index; |
| 2136 | inst_base->br = NON_BRANCH; | 1950 | inst_base->br = NON_BRANCH; |
| 2137 | 1951 | ||
| 2138 | inst_cream->inst = inst; | 1952 | inst_cream->inst = inst; |
| 2139 | inst_cream->get_addr = get_calc_addr_op(inst); | 1953 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2140 | 1954 | ||
| 2141 | if (BITS(inst, 12, 15) == 15) { | 1955 | if (BITS(inst, 12, 15) == 15) { |
| 2142 | inst_base->br = INDIRECT_BRANCH; | 1956 | inst_base->br = INDIRECT_BRANCH; |
| 2143 | } | 1957 | } |
| 2144 | return inst_base; | 1958 | return inst_base; |
| 2145 | } | 1959 | } |
| 2146 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) | 1960 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) |
| 2147 | { | 1961 | { |
| 2148 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1962 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2149 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1963 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2150 | 1964 | ||
| 2151 | inst_base->cond = BITS(inst, 28, 31); | 1965 | inst_base->cond = BITS(inst, 28, 31); |
| 2152 | inst_base->idx = index; | 1966 | inst_base->idx = index; |
| 2153 | inst_base->br = NON_BRANCH; | 1967 | inst_base->br = NON_BRANCH; |
| 2154 | 1968 | ||
| 2155 | inst_cream->inst = inst; | 1969 | inst_cream->inst = inst; |
| 2156 | inst_cream->get_addr = get_calc_addr_op(inst); | 1970 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2157 | 1971 | ||
| 2158 | if (BITS(inst, 12, 15) == 15) { | 1972 | if (BITS(inst, 12, 15) == 15) { |
| 2159 | inst_base->br = INDIRECT_BRANCH; | 1973 | inst_base->br = INDIRECT_BRANCH; |
| 2160 | } | 1974 | } |
| 2161 | return inst_base; | 1975 | return inst_base; |
| 2162 | } | 1976 | } |
| 2163 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) | 1977 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) |
| 2164 | { | 1978 | { |
| 2165 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1979 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2166 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1980 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2167 | 1981 | ||
| 2168 | inst_base->cond = BITS(inst, 28, 31); | 1982 | inst_base->cond = BITS(inst, 28, 31); |
| 2169 | inst_base->idx = index; | 1983 | inst_base->idx = index; |
| 2170 | inst_base->br = NON_BRANCH; | 1984 | inst_base->br = NON_BRANCH; |
| 2171 | 1985 | ||
| 2172 | inst_cream->inst = inst; | 1986 | inst_cream->inst = inst; |
| 2173 | inst_cream->get_addr = get_calc_addr_op(inst); | 1987 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2174 | 1988 | ||
| 2175 | if (BITS(inst, 12, 15) == 15) { | 1989 | if (BITS(inst, 12, 15) == 15) { |
| 2176 | inst_base->br = INDIRECT_BRANCH; | 1990 | inst_base->br = INDIRECT_BRANCH; |
| 2177 | } | 1991 | } |
| 2178 | return inst_base; | 1992 | return inst_base; |
| 2179 | } | 1993 | } |
| 2180 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) | 1994 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) |
| 2181 | { | 1995 | { |
| 2182 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1996 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2183 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1997 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2184 | 1998 | ||
| 2185 | inst_base->cond = BITS(inst, 28, 31); | 1999 | inst_base->cond = BITS(inst, 28, 31); |
| 2186 | inst_base->idx = index; | 2000 | inst_base->idx = index; |
| 2187 | inst_base->br = NON_BRANCH; | 2001 | inst_base->br = NON_BRANCH; |
| 2188 | 2002 | ||
| 2189 | inst_cream->inst = inst; | 2003 | inst_cream->inst = inst; |
| 2190 | if (I_BIT == 0) { | 2004 | if (I_BIT == 0) { |
| 2191 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 2005 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2192 | } else { | 2006 | } else { |
| 2193 | DEBUG_MSG; | 2007 | DEBUG_MSG; |
| 2194 | } | 2008 | } |
| 2195 | 2009 | ||
| 2196 | if (BITS(inst, 12, 15) == 15) { | 2010 | if (BITS(inst, 12, 15) == 15) { |
| 2197 | inst_base->br = INDIRECT_BRANCH; | 2011 | inst_base->br = INDIRECT_BRANCH; |
| 2198 | } | 2012 | } |
| 2199 | return inst_base; | 2013 | return inst_base; |
| 2200 | } | 2014 | } |
| 2201 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) | 2015 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) |
| 2202 | { | 2016 | { |
| 2203 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); | 2017 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); |
| 2204 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; | 2018 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; |
| 2205 | inst_base->cond = BITS(inst, 28, 31); | 2019 | inst_base->cond = BITS(inst, 28, 31); |
| 2206 | inst_base->idx = index; | 2020 | inst_base->idx = index; |
| 2207 | inst_base->br = NON_BRANCH; | 2021 | inst_base->br = NON_BRANCH; |
| 2208 | 2022 | ||
| 2209 | inst_cream->crn = BITS(inst, 16, 19); | 2023 | inst_cream->crn = BITS(inst, 16, 19); |
| 2210 | inst_cream->crm = BITS(inst, 0, 3); | 2024 | inst_cream->crm = BITS(inst, 0, 3); |
| 2211 | inst_cream->opcode_1 = BITS(inst, 21, 23); | 2025 | inst_cream->opcode_1 = BITS(inst, 21, 23); |
| 2212 | inst_cream->opcode_2 = BITS(inst, 5, 7); | 2026 | inst_cream->opcode_2 = BITS(inst, 5, 7); |
| 2213 | inst_cream->Rd = BITS(inst, 12, 15); | 2027 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2214 | inst_cream->cp_num = BITS(inst, 8, 11); | 2028 | inst_cream->cp_num = BITS(inst, 8, 11); |
| 2215 | inst_cream->inst = inst; | 2029 | inst_cream->inst = inst; |
| 2216 | return inst_base; | 2030 | return inst_base; |
| 2217 | } | 2031 | } |
| 2218 | 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;} | 2032 | ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MCRR"); } |
| 2219 | ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) | 2033 | ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) |
| 2220 | { | 2034 | { |
| 2221 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); | 2035 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); |
| 2222 | mla_inst *inst_cream = (mla_inst *)inst_base->component; | 2036 | mla_inst *inst_cream = (mla_inst *)inst_base->component; |
| 2223 | 2037 | ||
| 2224 | inst_base->cond = BITS(inst, 28, 31); | 2038 | inst_base->cond = BITS(inst, 28, 31); |
| 2225 | inst_base->idx = index; | 2039 | inst_base->idx = index; |
| 2226 | inst_base->br = NON_BRANCH; | 2040 | inst_base->br = NON_BRANCH; |
| 2227 | inst_base->load_r15 = 0; | 2041 | inst_base->load_r15 = 0; |
| 2228 | 2042 | ||
| 2229 | inst_cream->S = BIT(inst, 20); | 2043 | inst_cream->S = BIT(inst, 20); |
| 2230 | inst_cream->Rn = BITS(inst, 12, 15); | 2044 | inst_cream->Rn = BITS(inst, 12, 15); |
| 2231 | inst_cream->Rd = BITS(inst, 16, 19); | 2045 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2232 | inst_cream->Rs = BITS(inst, 8, 11); | 2046 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2233 | inst_cream->Rm = BITS(inst, 0, 3); | 2047 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2234 | 2048 | ||
| 2235 | if (CHECK_RM || CHECK_RN || CHECK_RS) | 2049 | if (CHECK_RM || CHECK_RN || CHECK_RS) |
| 2236 | inst_base->load_r15 = 1; | 2050 | inst_base->load_r15 = 1; |
| 2237 | 2051 | ||
| 2238 | return inst_base; | 2052 | return inst_base; |
| 2239 | } | 2053 | } |
| 2240 | ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) | 2054 | ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) |
| 2241 | { | 2055 | { |
| 2242 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); | 2056 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); |
| 2243 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 2057 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 2244 | 2058 | ||
| 2245 | inst_base->cond = BITS(inst, 28, 31); | 2059 | inst_base->cond = BITS(inst, 28, 31); |
| 2246 | inst_base->idx = index; | 2060 | inst_base->idx = index; |
| 2247 | inst_base->br = NON_BRANCH; | 2061 | inst_base->br = NON_BRANCH; |
| 2248 | 2062 | ||
| 2249 | inst_cream->I = BIT(inst, 25); | 2063 | inst_cream->I = BIT(inst, 25); |
| 2250 | inst_cream->S = BIT(inst, 20); | 2064 | inst_cream->S = BIT(inst, 20); |
| 2251 | inst_cream->Rd = BITS(inst, 12, 15); | 2065 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2252 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2066 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2253 | inst_cream->shtop_func = get_shtop(inst); | 2067 | inst_cream->shtop_func = get_shtop(inst); |
| 2254 | 2068 | ||
| 2255 | if (inst_cream->Rd == 15) { | 2069 | if (inst_cream->Rd == 15) { |
| 2256 | inst_base->br = INDIRECT_BRANCH; | 2070 | inst_base->br = INDIRECT_BRANCH; |
| 2257 | } | 2071 | } |
| 2258 | return inst_base; | 2072 | return inst_base; |
| 2259 | } | 2073 | } |
| 2260 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) | 2074 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) |
| 2261 | { | 2075 | { |
| 2262 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); | 2076 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); |
| 2263 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; | 2077 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; |
| 2264 | inst_base->cond = BITS(inst, 28, 31); | 2078 | inst_base->cond = BITS(inst, 28, 31); |
| 2265 | inst_base->idx = index; | 2079 | inst_base->idx = index; |
| 2266 | inst_base->br = NON_BRANCH; | 2080 | inst_base->br = NON_BRANCH; |
| 2267 | 2081 | ||
| 2268 | inst_cream->crn = BITS(inst, 16, 19); | 2082 | inst_cream->crn = BITS(inst, 16, 19); |
| 2269 | inst_cream->crm = BITS(inst, 0, 3); | 2083 | inst_cream->crm = BITS(inst, 0, 3); |
| 2270 | inst_cream->opcode_1 = BITS(inst, 21, 23); | 2084 | inst_cream->opcode_1 = BITS(inst, 21, 23); |
| 2271 | inst_cream->opcode_2 = BITS(inst, 5, 7); | 2085 | inst_cream->opcode_2 = BITS(inst, 5, 7); |
| 2272 | inst_cream->Rd = BITS(inst, 12, 15); | 2086 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2273 | inst_cream->cp_num = BITS(inst, 8, 11); | 2087 | inst_cream->cp_num = BITS(inst, 8, 11); |
| 2274 | inst_cream->inst = inst; | 2088 | inst_cream->inst = inst; |
| 2275 | return inst_base; | 2089 | return inst_base; |
| 2276 | } | 2090 | } |
| 2277 | 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;} | 2091 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("MRRC"); } |
| 2278 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) | 2092 | ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) |
| 2279 | { | 2093 | { |
| 2280 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); | 2094 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); |
| 2281 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; | 2095 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; |
| 2282 | 2096 | ||
| 2283 | inst_base->cond = BITS(inst, 28, 31); | 2097 | inst_base->cond = BITS(inst, 28, 31); |
| 2284 | inst_base->idx = index; | 2098 | inst_base->idx = index; |
| 2285 | inst_base->br = NON_BRANCH; | 2099 | inst_base->br = NON_BRANCH; |
| 2286 | 2100 | ||
| 2287 | inst_cream->Rd = BITS(inst, 12, 15); | 2101 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2288 | inst_cream->R = BIT(inst, 22); | 2102 | inst_cream->R = BIT(inst, 22); |
| 2289 | 2103 | ||
| 2290 | return inst_base; | 2104 | return inst_base; |
| 2291 | } | 2105 | } |
| 2292 | ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) | 2106 | ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) |
| 2293 | { | 2107 | { |
| 2294 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); | 2108 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); |
| 2295 | msr_inst *inst_cream = (msr_inst *)inst_base->component; | 2109 | msr_inst *inst_cream = (msr_inst *)inst_base->component; |
| 2296 | 2110 | ||
| 2297 | inst_base->cond = BITS(inst, 28, 31); | 2111 | inst_base->cond = BITS(inst, 28, 31); |
| 2298 | inst_base->idx = index; | 2112 | inst_base->idx = index; |
| 2299 | inst_base->br = NON_BRANCH; | 2113 | inst_base->br = NON_BRANCH; |
| 2300 | 2114 | ||
| 2301 | inst_cream->field_mask = BITS(inst, 16, 19); | 2115 | inst_cream->field_mask = BITS(inst, 16, 19); |
| 2302 | inst_cream->R = BIT(inst, 22); | 2116 | inst_cream->R = BIT(inst, 22); |
| 2303 | inst_cream->inst = inst; | 2117 | inst_cream->inst = inst; |
| 2304 | 2118 | ||
| 2305 | return inst_base; | 2119 | return inst_base; |
| 2306 | } | 2120 | } |
| 2307 | ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) | 2121 | ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) |
| 2308 | { | 2122 | { |
| 2309 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); | 2123 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); |
| 2310 | mul_inst *inst_cream = (mul_inst *)inst_base->component; | 2124 | mul_inst *inst_cream = (mul_inst *)inst_base->component; |
| 2311 | 2125 | ||
| 2312 | inst_base->cond = BITS(inst, 28, 31); | 2126 | inst_base->cond = BITS(inst, 28, 31); |
| 2313 | inst_base->idx = index; | 2127 | inst_base->idx = index; |
| 2314 | inst_base->br = NON_BRANCH; | 2128 | inst_base->br = NON_BRANCH; |
| 2315 | inst_base->load_r15 = 0; | 2129 | inst_base->load_r15 = 0; |
| 2316 | 2130 | ||
| 2317 | inst_cream->S = BIT(inst, 20); | 2131 | inst_cream->S = BIT(inst, 20); |
| 2318 | inst_cream->Rm = BITS(inst, 0, 3); | 2132 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2319 | inst_cream->Rs = BITS(inst, 8, 11); | 2133 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2320 | inst_cream->Rd = BITS(inst, 16, 19); | 2134 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2321 | 2135 | ||
| 2322 | if (CHECK_RM || CHECK_RS) | 2136 | if (CHECK_RM || CHECK_RS) |
| 2323 | inst_base->load_r15 = 1; | 2137 | inst_base->load_r15 = 1; |
| 2324 | return inst_base; | 2138 | return inst_base; |
| 2325 | } | 2139 | } |
| 2326 | ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) | 2140 | ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) |
| 2327 | { | 2141 | { |
| 2328 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); | 2142 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); |
| 2329 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; | 2143 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; |
| 2330 | 2144 | ||
| 2331 | inst_base->cond = BITS(inst, 28, 31); | 2145 | inst_base->cond = BITS(inst, 28, 31); |
| 2332 | inst_base->idx = index; | 2146 | inst_base->idx = index; |
| 2333 | inst_base->br = NON_BRANCH; | 2147 | inst_base->br = NON_BRANCH; |
| 2334 | 2148 | ||
| 2335 | inst_cream->I = BIT(inst, 25); | 2149 | inst_cream->I = BIT(inst, 25); |
| 2336 | inst_cream->S = BIT(inst, 20); | 2150 | inst_cream->S = BIT(inst, 20); |
| 2337 | inst_cream->Rd = BITS(inst, 12, 15); | 2151 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2338 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2152 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2339 | inst_cream->shtop_func = get_shtop(inst); | 2153 | inst_cream->shtop_func = get_shtop(inst); |
| 2340 | 2154 | ||
| 2341 | if (inst_cream->Rd == 15) { | 2155 | if (inst_cream->Rd == 15) { |
| 2342 | inst_base->br = INDIRECT_BRANCH; | 2156 | inst_base->br = INDIRECT_BRANCH; |
| 2343 | } | 2157 | } |
| 2344 | return inst_base; | 2158 | return inst_base; |
| 2345 | 2159 | ||
| 2346 | } | 2160 | } |
| 2347 | ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) | 2161 | ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) |
| 2348 | { | 2162 | { |
| 2349 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); | 2163 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); |
| 2350 | orr_inst *inst_cream = (orr_inst *)inst_base->component; | 2164 | orr_inst *inst_cream = (orr_inst *)inst_base->component; |
| 2351 | 2165 | ||
| 2352 | inst_base->cond = BITS(inst, 28, 31); | 2166 | inst_base->cond = BITS(inst, 28, 31); |
| 2353 | inst_base->idx = index; | 2167 | inst_base->idx = index; |
| 2354 | inst_base->br = NON_BRANCH; | 2168 | inst_base->br = NON_BRANCH; |
| 2355 | inst_base->load_r15 = 0; | 2169 | inst_base->load_r15 = 0; |
| 2356 | 2170 | ||
| 2357 | inst_cream->I = BIT(inst, 25); | 2171 | inst_cream->I = BIT(inst, 25); |
| 2358 | inst_cream->S = BIT(inst, 20); | 2172 | inst_cream->S = BIT(inst, 20); |
| 2359 | inst_cream->Rd = BITS(inst, 12, 15); | 2173 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2360 | inst_cream->Rn = BITS(inst, 16, 19); | 2174 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2361 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2175 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2362 | inst_cream->shtop_func = get_shtop(inst); | 2176 | inst_cream->shtop_func = get_shtop(inst); |
| 2363 | 2177 | ||
| 2364 | if (CHECK_RN) | 2178 | if (CHECK_RN) |
| 2365 | inst_base->load_r15 = 1; | 2179 | inst_base->load_r15 = 1; |
| 2366 | if (inst_cream->Rd == 15) { | 2180 | if (inst_cream->Rd == 15) { |
| 2367 | inst_base->br = INDIRECT_BRANCH; | 2181 | inst_base->br = INDIRECT_BRANCH; |
| 2368 | } | 2182 | } |
| 2369 | return inst_base; | 2183 | return inst_base; |
| 2370 | } | 2184 | } |
| 2371 | 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;} | 2185 | |
| 2372 | 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;} | 2186 | ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) |
| 2187 | { | ||
| 2188 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); | ||
| 2189 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | ||
| 2190 | |||
| 2191 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2192 | inst_base->idx = index; | ||
| 2193 | inst_base->br = NON_BRANCH; | ||
| 2194 | inst_base->load_r15 = 0; | ||
| 2195 | |||
| 2196 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2197 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2198 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2199 | inst_cream->imm = BITS(inst, 7, 11); | ||
| 2200 | |||
| 2201 | return inst_base; | ||
| 2202 | } | ||
| 2203 | |||
| 2204 | ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) | ||
| 2205 | { | ||
| 2206 | return INTERPRETER_TRANSLATE(pkhbt)(inst, index); | ||
| 2207 | } | ||
| 2208 | |||
| 2373 | ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) | 2209 | ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) |
| 2374 | { | 2210 | { |
| 2375 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); | 2211 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); |
| 2376 | 2212 | ||
| 2377 | inst_base->cond = BITS(inst, 28, 31); | 2213 | inst_base->cond = BITS(inst, 28, 31); |
| 2378 | inst_base->idx = index; | 2214 | inst_base->idx = index; |
| 2379 | inst_base->br = NON_BRANCH; | 2215 | inst_base->br = NON_BRANCH; |
| 2380 | inst_base->load_r15 = 0; | 2216 | inst_base->load_r15 = 0; |
| 2381 | 2217 | ||
| 2382 | return inst_base; | 2218 | return inst_base; |
| 2383 | } | 2219 | } |
| 2384 | 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;} | 2220 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } |
| 2385 | 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;} | 2221 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) |
| 2386 | 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;} | 2222 | { |
| 2387 | 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;} | 2223 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2388 | 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;} | 2224 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2389 | 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;} | 2225 | |
| 2390 | 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;} | 2226 | inst_base->cond = BITS(inst, 28, 31); |
| 2391 | 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;} | 2227 | inst_base->idx = index; |
| 2392 | 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;} | 2228 | inst_base->br = NON_BRANCH; |
| 2393 | 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;} | 2229 | inst_base->load_r15 = 0; |
| 2230 | |||
| 2231 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2232 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2233 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2234 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2235 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2236 | |||
| 2237 | return inst_base; | ||
| 2238 | } | ||
| 2239 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) | ||
| 2240 | { | ||
| 2241 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2242 | } | ||
| 2243 | ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) | ||
| 2244 | { | ||
| 2245 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2246 | } | ||
| 2247 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } | ||
| 2248 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } | ||
| 2249 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } | ||
| 2250 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) | ||
| 2251 | { | ||
| 2252 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2253 | } | ||
| 2254 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) | ||
| 2255 | { | ||
| 2256 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2257 | } | ||
| 2258 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) | ||
| 2259 | { | ||
| 2260 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | ||
| 2261 | } | ||
| 2394 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) | 2262 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) |
| 2395 | { | 2263 | { |
| 2396 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); | 2264 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); |
| 2397 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | 2265 | rev_inst *inst_cream = (rev_inst *)inst_base->component; |
| 2398 | 2266 | ||
| 2399 | inst_base->cond = BITS(inst, 28, 31); | 2267 | inst_base->cond = BITS(inst, 28, 31); |
| 2400 | inst_base->idx = index; | 2268 | inst_base->idx = index; |
| 2401 | inst_base->br = NON_BRANCH; | 2269 | inst_base->br = NON_BRANCH; |
| 2402 | inst_base->load_r15 = 0; | 2270 | inst_base->load_r15 = 0; |
| 2403 | 2271 | ||
| 2404 | inst_cream->Rm = BITS(inst, 0, 3); | 2272 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2405 | inst_cream->Rd = BITS(inst, 12, 15); | 2273 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2406 | 2274 | ||
| 2407 | return inst_base; | 2275 | return inst_base; |
| 2408 | } | 2276 | } |
| 2409 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ | 2277 | ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ |
| 2410 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); | 2278 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); |
| 2411 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | 2279 | rev_inst *inst_cream = (rev_inst *)inst_base->component; |
| 2412 | 2280 | ||
| 2413 | inst_base->cond = BITS(inst, 28, 31); | 2281 | inst_base->cond = BITS(inst, 28, 31); |
| 2414 | inst_base->idx = index; | 2282 | inst_base->idx = index; |
| 2415 | inst_base->br = NON_BRANCH; | 2283 | inst_base->br = NON_BRANCH; |
| 2416 | inst_base->load_r15 = 0; | 2284 | inst_base->load_r15 = 0; |
| 2417 | 2285 | ||
| 2418 | inst_cream->Rm = BITS(inst, 0, 3); | 2286 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2419 | inst_cream->Rd = BITS(inst, 12, 15); | 2287 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2420 | 2288 | ||
| 2421 | return inst_base; | 2289 | return inst_base; |
| 2422 | } | 2290 | } |
| 2423 | 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;} | 2291 | ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } |
| 2424 | 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;} | 2292 | ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); } |
| 2425 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) | 2293 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) |
| 2426 | { | 2294 | { |
| 2427 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); | 2295 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); |
| 2428 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; | 2296 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; |
| 2429 | 2297 | ||
| 2430 | inst_base->cond = BITS(inst, 28, 31); | 2298 | inst_base->cond = BITS(inst, 28, 31); |
| 2431 | inst_base->idx = index; | 2299 | inst_base->idx = index; |
| 2432 | inst_base->br = NON_BRANCH; | 2300 | inst_base->br = NON_BRANCH; |
| 2433 | inst_base->load_r15 = 0; | 2301 | inst_base->load_r15 = 0; |
| 2434 | 2302 | ||
| 2435 | inst_cream->I = BIT(inst, 25); | 2303 | inst_cream->I = BIT(inst, 25); |
| 2436 | inst_cream->S = BIT(inst, 20); | 2304 | inst_cream->S = BIT(inst, 20); |
| 2437 | inst_cream->Rn = BITS(inst, 16, 19); | 2305 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2438 | inst_cream->Rd = BITS(inst, 12, 15); | 2306 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2439 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2307 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2440 | inst_cream->shtop_func = get_shtop(inst); | 2308 | inst_cream->shtop_func = get_shtop(inst); |
| 2441 | if (CHECK_RN) | 2309 | if (CHECK_RN) |
| 2442 | inst_base->load_r15 = 1; | 2310 | inst_base->load_r15 = 1; |
| 2443 | 2311 | ||
| 2444 | if (inst_cream->Rd == 15) { | 2312 | if (inst_cream->Rd == 15) { |
| 2445 | inst_base->br = INDIRECT_BRANCH; | 2313 | inst_base->br = INDIRECT_BRANCH; |
| 2446 | } | 2314 | } |
| 2447 | return inst_base; | 2315 | return inst_base; |
| 2448 | } | 2316 | } |
| 2449 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) | 2317 | ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) |
| 2450 | { | 2318 | { |
| 2451 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); | 2319 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); |
| 2452 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; | 2320 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; |
| 2453 | 2321 | ||
| 2454 | inst_base->cond = BITS(inst, 28, 31); | 2322 | inst_base->cond = BITS(inst, 28, 31); |
| 2455 | inst_base->idx = index; | 2323 | inst_base->idx = index; |
| 2456 | inst_base->br = NON_BRANCH; | 2324 | inst_base->br = NON_BRANCH; |
| 2457 | inst_base->load_r15 = 0; | 2325 | inst_base->load_r15 = 0; |
| 2458 | 2326 | ||
| 2459 | inst_cream->I = BIT(inst, 25); | 2327 | inst_cream->I = BIT(inst, 25); |
| 2460 | inst_cream->S = BIT(inst, 20); | 2328 | inst_cream->S = BIT(inst, 20); |
| 2461 | inst_cream->Rn = BITS(inst, 16, 19); | 2329 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2462 | inst_cream->Rd = BITS(inst, 12, 15); | 2330 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2463 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2331 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2464 | inst_cream->shtop_func = get_shtop(inst); | 2332 | inst_cream->shtop_func = get_shtop(inst); |
| 2465 | if (CHECK_RN) | 2333 | if (CHECK_RN) |
| 2466 | inst_base->load_r15 = 1; | 2334 | inst_base->load_r15 = 1; |
| 2467 | 2335 | ||
| 2468 | if (inst_cream->Rd == 15) { | 2336 | if (inst_cream->Rd == 15) { |
| 2469 | inst_base->br = INDIRECT_BRANCH; | 2337 | inst_base->br = INDIRECT_BRANCH; |
| 2470 | } | 2338 | } |
| 2471 | return inst_base; | 2339 | return inst_base; |
| 2472 | } | 2340 | } |
| 2473 | 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;} | 2341 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); } |
| 2474 | 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;} | 2342 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) |
| 2475 | 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;} | 2343 | { |
| 2344 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | ||
| 2345 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 2346 | |||
| 2347 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2348 | inst_base->idx = index; | ||
| 2349 | inst_base->br = NON_BRANCH; | ||
| 2350 | inst_base->load_r15 = 0; | ||
| 2351 | |||
| 2352 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2353 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2354 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2355 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2356 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2357 | |||
| 2358 | return inst_base; | ||
| 2359 | } | ||
| 2360 | ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) | ||
| 2361 | { | ||
| 2362 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | ||
| 2363 | } | ||
| 2476 | ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) | 2364 | ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) |
| 2477 | { | 2365 | { |
| 2478 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); | 2366 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); |
| 2479 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; | 2367 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; |
| 2480 | 2368 | ||
| 2481 | inst_base->cond = BITS(inst, 28, 31); | 2369 | inst_base->cond = BITS(inst, 28, 31); |
| 2482 | inst_base->idx = index; | 2370 | inst_base->idx = index; |
| 2483 | inst_base->br = NON_BRANCH; | 2371 | inst_base->br = NON_BRANCH; |
| 2484 | inst_base->load_r15 = 0; | 2372 | inst_base->load_r15 = 0; |
| 2485 | 2373 | ||
| 2486 | inst_cream->I = BIT(inst, 25); | 2374 | inst_cream->I = BIT(inst, 25); |
| 2487 | inst_cream->S = BIT(inst, 20); | 2375 | inst_cream->S = BIT(inst, 20); |
| 2488 | inst_cream->Rn = BITS(inst, 16, 19); | 2376 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2489 | inst_cream->Rd = BITS(inst, 12, 15); | 2377 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2490 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2378 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2491 | inst_cream->shtop_func = get_shtop(inst); | 2379 | inst_cream->shtop_func = get_shtop(inst); |
| 2492 | if (CHECK_RN) | 2380 | if (CHECK_RN) |
| 2493 | inst_base->load_r15 = 1; | 2381 | inst_base->load_r15 = 1; |
| 2494 | 2382 | ||
| 2495 | if (inst_cream->Rd == 15) { | 2383 | if (inst_cream->Rd == 15) { |
| 2496 | inst_base->br = INDIRECT_BRANCH; | 2384 | inst_base->br = INDIRECT_BRANCH; |
| 2497 | } | 2385 | } |
| 2498 | return inst_base; | 2386 | return inst_base; |
| 2499 | } | 2387 | } |
| 2500 | 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;} | 2388 | ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) |
| 2501 | 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;} | 2389 | { |
| 2502 | 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;} | 2390 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2503 | 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;} | 2391 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2504 | 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;} | 2392 | |
| 2505 | 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;} | 2393 | inst_base->cond = BITS(inst, 28, 31); |
| 2506 | 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;} | 2394 | inst_base->idx = index; |
| 2507 | 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;} | 2395 | inst_base->br = NON_BRANCH; |
| 2396 | inst_base->load_r15 = 0; | ||
| 2397 | |||
| 2398 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2399 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2400 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2401 | inst_cream->op1 = BITS(inst, 20, 22); | ||
| 2402 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2403 | |||
| 2404 | return inst_base; | ||
| 2405 | } | ||
| 2406 | ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } | ||
| 2407 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); } | ||
| 2408 | ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD8"); } | ||
| 2409 | ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADDSUBX"); } | ||
| 2410 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB16"); } | ||
| 2411 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB8"); } | ||
| 2412 | ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); } | ||
| 2508 | ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) | 2413 | ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) |
| 2509 | { | 2414 | { |
| 2510 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); | 2415 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); |
| 2511 | smla_inst *inst_cream = (smla_inst *)inst_base->component; | 2416 | smla_inst *inst_cream = (smla_inst *)inst_base->component; |
| 2512 | 2417 | ||
| 2513 | inst_base->cond = BITS(inst, 28, 31); | 2418 | inst_base->cond = BITS(inst, 28, 31); |
| 2514 | inst_base->idx = index; | 2419 | inst_base->idx = index; |
| 2515 | inst_base->br = NON_BRANCH; | 2420 | inst_base->br = NON_BRANCH; |
| 2516 | inst_base->load_r15 = 0; | 2421 | inst_base->load_r15 = 0; |
| 2517 | 2422 | ||
| 2518 | inst_cream->x = BIT(inst, 5); | 2423 | inst_cream->x = BIT(inst, 5); |
| 2519 | inst_cream->y = BIT(inst, 6); | 2424 | inst_cream->y = BIT(inst, 6); |
| 2520 | inst_cream->Rm = BITS(inst, 0, 3); | 2425 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2521 | inst_cream->Rs = BITS(inst, 8, 11); | 2426 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2522 | inst_cream->Rd = BITS(inst, 16, 19); | 2427 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2523 | inst_cream->Rn = BITS(inst, 12, 15); | 2428 | inst_cream->Rn = BITS(inst, 12, 15); |
| 2524 | 2429 | ||
| 2525 | return inst_base; | 2430 | return inst_base; |
| 2526 | } | 2431 | } |
| 2527 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){ | 2432 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){ |
| 2528 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); | 2433 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); |
| 2529 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | 2434 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 2530 | 2435 | ||
| 2531 | inst_base->cond = BITS(inst, 28, 31); | 2436 | inst_base->cond = BITS(inst, 28, 31); |
| 2532 | inst_base->idx = index; | 2437 | inst_base->idx = index; |
| 2533 | inst_base->br = NON_BRANCH; | 2438 | inst_base->br = NON_BRANCH; |
| 2534 | inst_base->load_r15 = 0; | 2439 | inst_base->load_r15 = 0; |
| 2535 | 2440 | ||
| 2536 | inst_cream->m = BIT(inst, 4); | 2441 | inst_cream->m = BIT(inst, 4); |
| 2537 | inst_cream->Rn = BITS(inst, 0, 3); | 2442 | inst_cream->Rn = BITS(inst, 0, 3); |
| 2538 | inst_cream->Rm = BITS(inst, 8, 11); | 2443 | inst_cream->Rm = BITS(inst, 8, 11); |
| 2539 | inst_cream->Rd = BITS(inst, 16, 19); | 2444 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2540 | inst_cream->Ra = BITS(inst, 12, 15); | 2445 | inst_cream->Ra = BITS(inst, 12, 15); |
| 2541 | 2446 | ||
| 2542 | if (CHECK_RM ) | 2447 | if (CHECK_RM ) |
| 2543 | inst_base->load_r15 = 1; | 2448 | inst_base->load_r15 = 1; |
| 2544 | return inst_base; | 2449 | return inst_base; |
| 2545 | } | 2450 | } |
| 2546 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) | 2451 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) |
| 2547 | { | 2452 | { |
| 2548 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); | 2453 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); |
| 2549 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 2454 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 2550 | 2455 | ||
| 2551 | inst_base->cond = BITS(inst, 28, 31); | 2456 | inst_base->cond = BITS(inst, 28, 31); |
| 2552 | inst_base->idx = index; | 2457 | inst_base->idx = index; |
| 2553 | inst_base->br = NON_BRANCH; | 2458 | inst_base->br = NON_BRANCH; |
| 2554 | inst_base->load_r15 = 0; | 2459 | inst_base->load_r15 = 0; |
| 2555 | 2460 | ||
| 2556 | inst_cream->S = BIT(inst, 20); | 2461 | inst_cream->S = BIT(inst, 20); |
| 2557 | inst_cream->Rm = BITS(inst, 0, 3); | 2462 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2558 | inst_cream->Rs = BITS(inst, 8, 11); | 2463 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2559 | inst_cream->RdHi = BITS(inst, 16, 19); | 2464 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 2560 | inst_cream->RdLo = BITS(inst, 12, 15); | 2465 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 2561 | 2466 | ||
| 2562 | if (CHECK_RM || CHECK_RS) | 2467 | if (CHECK_RM || CHECK_RS) |
| 2563 | inst_base->load_r15 = 1; | 2468 | inst_base->load_r15 = 1; |
| 2564 | return inst_base; | 2469 | return inst_base; |
| 2565 | } | 2470 | } |
| 2566 | 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;} | 2471 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); } |
| 2567 | 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;} | 2472 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); } |
| 2568 | 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;} | 2473 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); } |
| 2569 | 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;} | 2474 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSD"); } |
| 2570 | 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;} | 2475 | ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSLD"); } |
| 2571 | 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;} | 2476 | ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLA"); } |
| 2572 | 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;} | 2477 | ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLS"); } |
| 2573 | 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;} | 2478 | ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMUL"); } |
| 2574 | 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;} | 2479 | ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); } |
| 2575 | ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) | 2480 | ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) |
| 2576 | { | 2481 | { |
| 2577 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); | 2482 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); |
| 2578 | smul_inst *inst_cream = (smul_inst *)inst_base->component; | 2483 | smul_inst *inst_cream = (smul_inst *)inst_base->component; |
| 2579 | 2484 | ||
| 2580 | inst_base->cond = BITS(inst, 28, 31); | 2485 | inst_base->cond = BITS(inst, 28, 31); |
| 2581 | inst_base->idx = index; | 2486 | inst_base->idx = index; |
| 2582 | inst_base->br = NON_BRANCH; | 2487 | inst_base->br = NON_BRANCH; |
| 2583 | inst_base->load_r15 = 0; | 2488 | inst_base->load_r15 = 0; |
| 2584 | 2489 | ||
| 2585 | inst_cream->Rd = BITS(inst, 16, 19); | 2490 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2586 | inst_cream->Rs = BITS(inst, 8, 11); | 2491 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2587 | inst_cream->Rm = BITS(inst, 0, 3); | 2492 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2588 | 2493 | ||
| 2589 | inst_cream->x = BIT(inst, 5); | 2494 | inst_cream->x = BIT(inst, 5); |
| 2590 | inst_cream->y = BIT(inst, 6); | 2495 | inst_cream->y = BIT(inst, 6); |
| 2591 | 2496 | ||
| 2592 | if (CHECK_RM || CHECK_RS) | 2497 | if (CHECK_RM || CHECK_RS) |
| 2593 | inst_base->load_r15 = 1; | 2498 | inst_base->load_r15 = 1; |
| 2594 | return inst_base; | 2499 | return inst_base; |
| 2595 | 2500 | ||
| 2596 | } | 2501 | } |
| 2597 | ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) | 2502 | ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) |
| 2598 | { | 2503 | { |
| 2599 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); | 2504 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); |
| 2600 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 2505 | umull_inst *inst_cream = (umull_inst *)inst_base->component; |
| 2601 | 2506 | ||
| 2602 | inst_base->cond = BITS(inst, 28, 31); | 2507 | inst_base->cond = BITS(inst, 28, 31); |
| 2603 | inst_base->idx = index; | 2508 | inst_base->idx = index; |
| 2604 | inst_base->br = NON_BRANCH; | 2509 | inst_base->br = NON_BRANCH; |
| 2605 | inst_base->load_r15 = 0; | 2510 | inst_base->load_r15 = 0; |
| 2606 | 2511 | ||
| 2607 | inst_cream->S = BIT(inst, 20); | 2512 | inst_cream->S = BIT(inst, 20); |
| 2608 | inst_cream->Rm = BITS(inst, 0, 3); | 2513 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2609 | inst_cream->Rs = BITS(inst, 8, 11); | 2514 | inst_cream->Rs = BITS(inst, 8, 11); |
| 2610 | inst_cream->RdHi = BITS(inst, 16, 19); | 2515 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 2611 | inst_cream->RdLo = BITS(inst, 12, 15); | 2516 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 2612 | 2517 | ||
| 2613 | if (CHECK_RM || CHECK_RS) | 2518 | if (CHECK_RM || CHECK_RS) |
| 2614 | inst_base->load_r15 = 1; | 2519 | inst_base->load_r15 = 1; |
| 2615 | return inst_base; | 2520 | return inst_base; |
| 2616 | } | 2521 | } |
| 2617 | 2522 | ||
| 2618 | ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) | 2523 | ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) |
| 2619 | { | 2524 | { |
| 2620 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); | 2525 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); |
| 2621 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | 2526 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 2622 | 2527 | ||
| 2623 | inst_base->cond = BITS(inst, 28, 31); | 2528 | inst_base->cond = BITS(inst, 28, 31); |
| 2624 | inst_base->idx = index; | 2529 | inst_base->idx = index; |
| 2625 | inst_base->br = NON_BRANCH; | 2530 | inst_base->br = NON_BRANCH; |
| 2626 | inst_base->load_r15 = 0; | 2531 | inst_base->load_r15 = 0; |
| 2627 | 2532 | ||
| 2628 | inst_cream->m = BIT(inst, 6); | 2533 | inst_cream->m = BIT(inst, 6); |
| 2629 | inst_cream->Rm = BITS(inst, 8, 11); | 2534 | inst_cream->Rm = BITS(inst, 8, 11); |
| 2630 | inst_cream->Rn = BITS(inst, 0, 3); | 2535 | inst_cream->Rn = BITS(inst, 0, 3); |
| 2631 | inst_cream->Rd = BITS(inst, 16, 19); | 2536 | inst_cream->Rd = BITS(inst, 16, 19); |
| 2632 | 2537 | ||
| 2633 | if (CHECK_RM || CHECK_RN) | 2538 | if (CHECK_RM || CHECK_RN) |
| 2634 | inst_base->load_r15 = 1; | 2539 | inst_base->load_r15 = 1; |
| 2635 | return inst_base; | 2540 | return inst_base; |
| 2636 | } | 2541 | } |
| 2637 | 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;} | 2542 | ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); } |
| 2638 | 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;} | 2543 | ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); } |
| 2639 | 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;} | 2544 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) |
| 2640 | 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;} | 2545 | { |
| 2641 | 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;} | 2546 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst)); |
| 2642 | 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;} | 2547 | ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; |
| 2643 | 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;} | 2548 | |
| 2549 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2550 | inst_base->idx = index; | ||
| 2551 | inst_base->br = NON_BRANCH; | ||
| 2552 | inst_base->load_r15 = 0; | ||
| 2553 | |||
| 2554 | inst_cream->Rn = BITS(inst, 0, 3); | ||
| 2555 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2556 | inst_cream->imm5 = BITS(inst, 7, 11); | ||
| 2557 | inst_cream->sat_imm = BITS(inst, 16, 20); | ||
| 2558 | inst_cream->shift_type = BIT(inst, 6); | ||
| 2559 | |||
| 2560 | return inst_base; | ||
| 2561 | } | ||
| 2562 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT16"); } | ||
| 2563 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } | ||
| 2564 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) | ||
| 2565 | { | ||
| 2566 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | ||
| 2567 | } | ||
| 2568 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) | ||
| 2569 | { | ||
| 2570 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | ||
| 2571 | } | ||
| 2644 | ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) | 2572 | ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) |
| 2645 | { | 2573 | { |
| 2646 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); | 2574 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); |
| 2647 | inst_base->cond = BITS(inst, 28, 31); | 2575 | inst_base->cond = BITS(inst, 28, 31); |
| 2648 | inst_base->idx = index; | 2576 | inst_base->idx = index; |
| 2649 | inst_base->br = NON_BRANCH; | 2577 | inst_base->br = NON_BRANCH; |
| 2650 | 2578 | ||
| 2651 | return inst_base; | 2579 | return inst_base; |
| 2652 | } | 2580 | } |
| 2653 | ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) | 2581 | ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) |
| 2654 | { | 2582 | { |
| 2655 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2583 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2656 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2584 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2657 | 2585 | ||
| 2658 | inst_base->cond = BITS(inst, 28, 31); | 2586 | inst_base->cond = BITS(inst, 28, 31); |
| 2659 | inst_base->idx = index; | 2587 | inst_base->idx = index; |
| 2660 | inst_base->br = NON_BRANCH; | 2588 | inst_base->br = NON_BRANCH; |
| 2661 | 2589 | ||
| 2662 | inst_cream->inst = inst; | 2590 | inst_cream->inst = inst; |
| 2663 | inst_cream->get_addr = get_calc_addr_op(inst); | 2591 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2664 | return inst_base; | 2592 | return inst_base; |
| 2665 | } | 2593 | } |
| 2666 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) | 2594 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) |
| 2667 | { | 2595 | { |
| 2668 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); | 2596 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); |
| 2669 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | 2597 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; |
| 2670 | 2598 | ||
| 2671 | inst_base->cond = BITS(inst, 28, 31); | 2599 | inst_base->cond = BITS(inst, 28, 31); |
| 2672 | inst_base->idx = index; | 2600 | inst_base->idx = index; |
| 2673 | inst_base->br = NON_BRANCH; | 2601 | inst_base->br = NON_BRANCH; |
| 2674 | inst_base->load_r15 = 0; | 2602 | inst_base->load_r15 = 0; |
| 2675 | 2603 | ||
| 2676 | inst_cream->Rd = BITS(inst, 12, 15); | 2604 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2677 | inst_cream->Rm = BITS(inst, 0, 3); | 2605 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2678 | inst_cream->rotate = BITS(inst, 10, 11); | 2606 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2679 | 2607 | ||
| 2680 | if (CHECK_RM) | 2608 | if (CHECK_RM) |
| 2681 | inst_base->load_r15 = 1; | 2609 | inst_base->load_r15 = 1; |
| 2682 | return inst_base; | 2610 | return inst_base; |
| 2683 | } | 2611 | } |
| 2684 | ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) | 2612 | ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) |
| 2685 | { | 2613 | { |
| 2686 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2614 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2687 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2615 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2688 | 2616 | ||
| 2689 | inst_base->cond = BITS(inst, 28, 31); | 2617 | inst_base->cond = BITS(inst, 28, 31); |
| 2690 | inst_base->idx = index; | 2618 | inst_base->idx = index; |
| 2691 | inst_base->br = NON_BRANCH; | 2619 | inst_base->br = NON_BRANCH; |
| 2692 | 2620 | ||
| 2693 | inst_cream->inst = inst; | 2621 | inst_cream->inst = inst; |
| 2694 | inst_cream->get_addr = get_calc_addr_op(inst); | 2622 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2695 | 2623 | ||
| 2696 | if (BITS(inst, 12, 15) == 15) { | 2624 | if (BITS(inst, 12, 15) == 15) { |
| 2697 | inst_base->br = INDIRECT_BRANCH; | 2625 | inst_base->br = INDIRECT_BRANCH; |
| 2698 | } | 2626 | } |
| 2699 | return inst_base; | 2627 | return inst_base; |
| 2700 | } | 2628 | } |
| 2701 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) | 2629 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) |
| 2702 | { | 2630 | { |
| 2703 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); | 2631 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); |
| 2704 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; | 2632 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; |
| 2705 | 2633 | ||
| 2706 | inst_base->cond = BITS(inst, 28, 31); | 2634 | inst_base->cond = BITS(inst, 28, 31); |
| 2707 | inst_base->idx = index; | 2635 | inst_base->idx = index; |
| 2708 | inst_base->br = NON_BRANCH; | 2636 | inst_base->br = NON_BRANCH; |
| 2709 | inst_base->load_r15 = 0; | 2637 | inst_base->load_r15 = 0; |
| 2710 | 2638 | ||
| 2711 | inst_cream->Rd = BITS(inst, 12, 15); | 2639 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2712 | inst_cream->rotate = BITS(inst, 10, 11); | 2640 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2713 | inst_cream->Rm = BITS(inst, 0, 3); | 2641 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2714 | 2642 | ||
| 2715 | if (CHECK_RM) | 2643 | if (CHECK_RM) |
| 2716 | inst_base->load_r15 = 1; | 2644 | inst_base->load_r15 = 1; |
| 2717 | return inst_base; | 2645 | return inst_base; |
| 2718 | } | 2646 | } |
| 2719 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) | 2647 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) |
| 2720 | { | 2648 | { |
| 2721 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); | 2649 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); |
| 2722 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; | 2650 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; |
| 2723 | 2651 | ||
| 2724 | inst_base->cond = BITS(inst, 28, 31); | 2652 | inst_base->cond = BITS(inst, 28, 31); |
| 2725 | inst_base->idx = index; | 2653 | inst_base->idx = index; |
| 2726 | inst_base->br = NON_BRANCH; | 2654 | inst_base->br = NON_BRANCH; |
| 2727 | inst_base->load_r15 = 0; | 2655 | inst_base->load_r15 = 0; |
| 2728 | 2656 | ||
| 2729 | inst_cream->Rd = BITS(inst, 12, 15); | 2657 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2730 | inst_cream->rotate = BITS(inst, 10, 11); | 2658 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2731 | inst_cream->Rm = BITS(inst, 0, 3); | 2659 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2732 | inst_cream->Rn = BITS(inst, 16, 19); | 2660 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2733 | 2661 | ||
| 2734 | return inst_base; | 2662 | return inst_base; |
| 2735 | } | 2663 | } |
| 2736 | ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) | 2664 | ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) |
| 2737 | { | 2665 | { |
| 2738 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2666 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2739 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2667 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2740 | 2668 | ||
| 2741 | inst_base->cond = BITS(inst, 28, 31); | 2669 | inst_base->cond = BITS(inst, 28, 31); |
| 2742 | inst_base->idx = index; | 2670 | inst_base->idx = index; |
| 2743 | inst_base->br = NON_BRANCH; | 2671 | inst_base->br = NON_BRANCH; |
| 2744 | 2672 | ||
| 2745 | inst_cream->inst = inst; | 2673 | inst_cream->inst = inst; |
| 2746 | inst_cream->get_addr = get_calc_addr_op(inst); | 2674 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2747 | 2675 | ||
| 2748 | if (BITS(inst, 12, 15) == 15) { | 2676 | if (BITS(inst, 12, 15) == 15) { |
| 2749 | inst_base->br = INDIRECT_BRANCH; | 2677 | inst_base->br = INDIRECT_BRANCH; |
| 2750 | } | 2678 | } |
| 2751 | return inst_base; | 2679 | return inst_base; |
| 2752 | } | 2680 | } |
| 2753 | ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) | 2681 | ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) |
| 2754 | { | 2682 | { |
| 2755 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2683 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2756 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2684 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2757 | 2685 | ||
| 2758 | inst_base->cond = BITS(inst, 28, 31); | 2686 | inst_base->cond = BITS(inst, 28, 31); |
| 2759 | inst_base->idx = index; | 2687 | inst_base->idx = index; |
| 2760 | inst_base->br = NON_BRANCH; | 2688 | inst_base->br = NON_BRANCH; |
| 2761 | 2689 | ||
| 2762 | inst_cream->inst = inst; | 2690 | inst_cream->inst = inst; |
| 2763 | // inst_cream->get_addr = get_calc_addr_op(inst); | 2691 | // inst_cream->get_addr = get_calc_addr_op(inst); |
| 2764 | if (I_BIT == 0) { | 2692 | if (I_BIT == 0) { |
| 2765 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 2693 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2766 | } else { | 2694 | } else { |
| 2767 | DEBUG_MSG; | 2695 | DEBUG_MSG; |
| 2768 | } | 2696 | } |
| 2769 | 2697 | ||
| 2770 | if (BITS(inst, 12, 15) == 15) { | 2698 | if (BITS(inst, 12, 15) == 15) { |
| 2771 | inst_base->br = INDIRECT_BRANCH; | 2699 | inst_base->br = INDIRECT_BRANCH; |
| 2772 | } | 2700 | } |
| 2773 | return inst_base; | 2701 | return inst_base; |
| 2774 | } | 2702 | } |
| 2775 | ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ | 2703 | ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ |
| 2776 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2704 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2777 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2705 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2778 | 2706 | ||
| 2779 | inst_base->cond = BITS(inst, 28, 31); | 2707 | inst_base->cond = BITS(inst, 28, 31); |
| 2780 | inst_base->idx = index; | 2708 | inst_base->idx = index; |
| 2781 | inst_base->br = NON_BRANCH; | 2709 | inst_base->br = NON_BRANCH; |
| 2782 | 2710 | ||
| 2783 | inst_cream->inst = inst; | 2711 | inst_cream->inst = inst; |
| 2784 | inst_cream->get_addr = get_calc_addr_op(inst); | 2712 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2785 | 2713 | ||
| 2786 | if (BITS(inst, 12, 15) == 15) { | 2714 | if (BITS(inst, 12, 15) == 15) { |
| 2787 | inst_base->br = INDIRECT_BRANCH; | 2715 | inst_base->br = INDIRECT_BRANCH; |
| 2788 | } | 2716 | } |
| 2789 | return inst_base; | 2717 | return inst_base; |
| 2790 | } | 2718 | } |
| 2791 | ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) | 2719 | ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) |
| 2792 | { | 2720 | { |
| 2793 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2721 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2794 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2722 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2795 | 2723 | ||
| 2796 | inst_base->cond = BITS(inst, 28, 31); | 2724 | inst_base->cond = BITS(inst, 28, 31); |
| 2797 | inst_base->idx = index; | 2725 | inst_base->idx = index; |
| 2798 | inst_base->br = NON_BRANCH; | 2726 | inst_base->br = NON_BRANCH; |
| 2799 | 2727 | ||
| 2800 | inst_cream->inst = inst; | 2728 | inst_cream->inst = inst; |
| 2801 | inst_cream->get_addr = get_calc_addr_op(inst); | 2729 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2802 | 2730 | ||
| 2803 | if (BITS(inst, 12, 15) == 15) { | 2731 | if (BITS(inst, 12, 15) == 15) { |
| 2804 | inst_base->br = INDIRECT_BRANCH; | 2732 | inst_base->br = INDIRECT_BRANCH; |
| 2805 | } | 2733 | } |
| 2806 | return inst_base; | 2734 | return inst_base; |
| 2807 | } | 2735 | } |
| 2808 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) | 2736 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) |
| 2809 | { | 2737 | { |
| 2810 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2738 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2811 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2739 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2812 | 2740 | ||
| 2813 | inst_base->cond = BITS(inst, 28, 31); | 2741 | inst_base->cond = BITS(inst, 28, 31); |
| 2814 | inst_base->idx = index; | 2742 | inst_base->idx = index; |
| 2815 | inst_base->br = NON_BRANCH; | 2743 | inst_base->br = NON_BRANCH; |
| 2816 | 2744 | ||
| 2817 | inst_cream->inst = inst; | 2745 | inst_cream->inst = inst; |
| 2818 | inst_cream->get_addr = get_calc_addr_op(inst); | 2746 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2819 | 2747 | ||
| 2820 | if (BITS(inst, 12, 15) == 15) { | 2748 | if (BITS(inst, 12, 15) == 15) { |
| 2821 | inst_base->br = INDIRECT_BRANCH; | 2749 | inst_base->br = INDIRECT_BRANCH; |
| 2822 | } | 2750 | } |
| 2823 | return inst_base; | 2751 | return inst_base; |
| 2824 | } | 2752 | } |
| 2825 | ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) | 2753 | ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) |
| 2826 | { | 2754 | { |
| 2827 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2755 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2828 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2756 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2829 | 2757 | ||
| 2830 | inst_base->cond = BITS(inst, 28, 31); | 2758 | inst_base->cond = BITS(inst, 28, 31); |
| 2831 | inst_base->idx = index; | 2759 | inst_base->idx = index; |
| 2832 | inst_base->br = NON_BRANCH; | 2760 | inst_base->br = NON_BRANCH; |
| 2833 | 2761 | ||
| 2834 | inst_cream->inst = inst; | 2762 | inst_cream->inst = inst; |
| 2835 | inst_cream->get_addr = get_calc_addr_op(inst); | 2763 | inst_cream->get_addr = get_calc_addr_op(inst); |
| 2836 | 2764 | ||
| 2837 | if (BITS(inst, 12, 15) == 15) { | 2765 | if (BITS(inst, 12, 15) == 15) { |
| 2838 | inst_base->br = INDIRECT_BRANCH; | 2766 | inst_base->br = INDIRECT_BRANCH; |
| 2839 | } | 2767 | } |
| 2840 | return inst_base; | 2768 | return inst_base; |
| 2841 | } | 2769 | } |
| 2842 | ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) | 2770 | ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) |
| 2843 | { | 2771 | { |
| 2844 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2772 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); |
| 2845 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2773 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 2846 | 2774 | ||
| 2847 | inst_base->cond = BITS(inst, 28, 31); | 2775 | inst_base->cond = BITS(inst, 28, 31); |
| 2848 | inst_base->idx = index; | 2776 | inst_base->idx = index; |
| 2849 | inst_base->br = NON_BRANCH; | 2777 | inst_base->br = NON_BRANCH; |
| 2850 | 2778 | ||
| 2851 | inst_cream->inst = inst; | 2779 | inst_cream->inst = inst; |
| 2852 | if (I_BIT == 0) { | 2780 | if (I_BIT == 0) { |
| 2853 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); | 2781 | inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); |
| 2854 | } else { | 2782 | } else { |
| 2855 | DEBUG_MSG; | 2783 | DEBUG_MSG; |
| 2856 | } | 2784 | } |
| 2857 | 2785 | ||
| 2858 | if (BITS(inst, 12, 15) == 15) { | 2786 | if (BITS(inst, 12, 15) == 15) { |
| 2859 | inst_base->br = INDIRECT_BRANCH; | 2787 | inst_base->br = INDIRECT_BRANCH; |
| 2860 | } | 2788 | } |
| 2861 | return inst_base; | 2789 | return inst_base; |
| 2862 | } | 2790 | } |
| 2863 | ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) | 2791 | ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) |
| 2864 | { | 2792 | { |
| 2865 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); | 2793 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); |
| 2866 | sub_inst *inst_cream = (sub_inst *)inst_base->component; | 2794 | sub_inst *inst_cream = (sub_inst *)inst_base->component; |
| 2867 | 2795 | ||
| 2868 | inst_base->cond = BITS(inst, 28, 31); | 2796 | inst_base->cond = BITS(inst, 28, 31); |
| 2869 | inst_base->idx = index; | 2797 | inst_base->idx = index; |
| 2870 | inst_base->br = NON_BRANCH; | 2798 | inst_base->br = NON_BRANCH; |
| 2871 | inst_base->load_r15 = 0; | 2799 | inst_base->load_r15 = 0; |
| 2872 | 2800 | ||
| 2873 | inst_cream->I = BIT(inst, 25); | 2801 | inst_cream->I = BIT(inst, 25); |
| 2874 | inst_cream->S = BIT(inst, 20); | 2802 | inst_cream->S = BIT(inst, 20); |
| 2875 | inst_cream->Rn = BITS(inst, 16, 19); | 2803 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2876 | inst_cream->Rd = BITS(inst, 12, 15); | 2804 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2877 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2805 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2878 | inst_cream->shtop_func = get_shtop(inst); | 2806 | inst_cream->shtop_func = get_shtop(inst); |
| 2879 | if (inst_cream->Rd == 15) { | 2807 | if (inst_cream->Rd == 15) { |
| 2880 | inst_base->br = INDIRECT_BRANCH; | 2808 | inst_base->br = INDIRECT_BRANCH; |
| 2881 | } | 2809 | } |
| 2882 | if (CHECK_RN) | 2810 | if (CHECK_RN) |
| 2883 | inst_base->load_r15 = 1; | 2811 | inst_base->load_r15 = 1; |
| 2884 | 2812 | ||
| 2885 | return inst_base; | 2813 | return inst_base; |
| 2886 | } | 2814 | } |
| 2887 | ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) | 2815 | ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) |
| 2888 | { | 2816 | { |
| 2889 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); | 2817 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); |
| 2890 | swi_inst *inst_cream = (swi_inst *)inst_base->component; | 2818 | swi_inst *inst_cream = (swi_inst *)inst_base->component; |
| 2891 | 2819 | ||
| 2892 | inst_base->cond = BITS(inst, 28, 31); | 2820 | inst_base->cond = BITS(inst, 28, 31); |
| 2893 | inst_base->idx = index; | 2821 | inst_base->idx = index; |
| 2894 | inst_base->br = NON_BRANCH; | 2822 | inst_base->br = NON_BRANCH; |
| 2895 | 2823 | ||
| 2896 | inst_cream->num = BITS(inst, 0, 23); | 2824 | inst_cream->num = BITS(inst, 0, 23); |
| 2897 | return inst_base; | 2825 | return inst_base; |
| 2898 | } | 2826 | } |
| 2899 | ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) | 2827 | ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) |
| 2900 | { | 2828 | { |
| 2901 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); | 2829 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); |
| 2902 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 2830 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 2903 | 2831 | ||
| 2904 | inst_base->cond = BITS(inst, 28, 31); | 2832 | inst_base->cond = BITS(inst, 28, 31); |
| 2905 | inst_base->idx = index; | 2833 | inst_base->idx = index; |
| 2906 | inst_base->br = NON_BRANCH; | 2834 | inst_base->br = NON_BRANCH; |
| 2907 | 2835 | ||
| 2908 | inst_cream->Rn = BITS(inst, 16, 19); | 2836 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2909 | inst_cream->Rd = BITS(inst, 12, 15); | 2837 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2910 | inst_cream->Rm = BITS(inst, 0, 3); | 2838 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2911 | 2839 | ||
| 2912 | if (inst_cream->Rd == 15) { | 2840 | if (inst_cream->Rd == 15) { |
| 2913 | inst_base->br = INDIRECT_BRANCH; | 2841 | inst_base->br = INDIRECT_BRANCH; |
| 2914 | } | 2842 | } |
| 2915 | return inst_base; | 2843 | return inst_base; |
| 2916 | } | 2844 | } |
| 2917 | ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ | 2845 | ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ |
| 2918 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); | 2846 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); |
| 2919 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 2847 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 2920 | 2848 | ||
| 2921 | inst_base->cond = BITS(inst, 28, 31); | 2849 | inst_base->cond = BITS(inst, 28, 31); |
| 2922 | inst_base->idx = index; | 2850 | inst_base->idx = index; |
| 2923 | inst_base->br = NON_BRANCH; | 2851 | inst_base->br = NON_BRANCH; |
| 2924 | 2852 | ||
| 2925 | inst_cream->Rn = BITS(inst, 16, 19); | 2853 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2926 | inst_cream->Rd = BITS(inst, 12, 15); | 2854 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2927 | inst_cream->Rm = BITS(inst, 0, 3); | 2855 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2928 | 2856 | ||
| 2929 | if (inst_cream->Rd == 15) { | 2857 | if (inst_cream->Rd == 15) { |
| 2930 | inst_base->br = INDIRECT_BRANCH; | 2858 | inst_base->br = INDIRECT_BRANCH; |
| 2931 | } | 2859 | } |
| 2932 | return inst_base; | 2860 | return inst_base; |
| 2933 | } | 2861 | } |
| 2934 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ | 2862 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ |
| 2935 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); | 2863 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); |
| 2936 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; | 2864 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; |
| 2937 | 2865 | ||
| 2938 | inst_base->cond = BITS(inst, 28, 31); | 2866 | inst_base->cond = BITS(inst, 28, 31); |
| 2939 | inst_base->idx = index; | 2867 | inst_base->idx = index; |
| 2940 | inst_base->br = NON_BRANCH; | 2868 | inst_base->br = NON_BRANCH; |
| 2941 | inst_base->load_r15 = 0; | 2869 | inst_base->load_r15 = 0; |
| 2942 | 2870 | ||
| 2943 | inst_cream->Rd = BITS(inst, 12, 15); | 2871 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2944 | inst_cream->rotate = BITS(inst, 10, 11); | 2872 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2945 | inst_cream->Rm = BITS(inst, 0, 3); | 2873 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2946 | inst_cream->Rn = BITS(inst, 16, 19); | 2874 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2947 | 2875 | ||
| 2948 | return inst_base; | 2876 | return inst_base; |
| 2949 | } | 2877 | } |
| 2950 | 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;} | 2878 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); } |
| 2951 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ | 2879 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){ |
| 2952 | DEBUG_LOG(ARM11, "in func %s, SXTAH untested\n", __func__); | 2880 | LOG_WARNING(Core_ARM11, "SXTAH untested"); |
| 2953 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); | 2881 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); |
| 2954 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; | 2882 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; |
| 2955 | 2883 | ||
| 2956 | inst_base->cond = BITS(inst, 28, 31); | 2884 | inst_base->cond = BITS(inst, 28, 31); |
| 2957 | inst_base->idx = index; | 2885 | inst_base->idx = index; |
| 2958 | inst_base->br = NON_BRANCH; | 2886 | inst_base->br = NON_BRANCH; |
| 2959 | inst_base->load_r15 = 0; | 2887 | inst_base->load_r15 = 0; |
| 2960 | 2888 | ||
| 2961 | inst_cream->Rd = BITS(inst, 12, 15); | 2889 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2962 | inst_cream->rotate = BITS(inst, 10, 11); | 2890 | inst_cream->rotate = BITS(inst, 10, 11); |
| 2963 | inst_cream->Rm = BITS(inst, 0, 3); | 2891 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2964 | inst_cream->Rn = BITS(inst, 16, 19); | 2892 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2965 | 2893 | ||
| 2966 | return inst_base; | 2894 | return inst_base; |
| 2967 | } | 2895 | } |
| 2968 | 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;} | 2896 | ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); } |
| 2969 | ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) | 2897 | ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) |
| 2970 | { | 2898 | { |
| 2971 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); | 2899 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); |
| 2972 | teq_inst *inst_cream = (teq_inst *)inst_base->component; | 2900 | teq_inst *inst_cream = (teq_inst *)inst_base->component; |
| 2973 | 2901 | ||
| 2974 | inst_base->cond = BITS(inst, 28, 31); | 2902 | inst_base->cond = BITS(inst, 28, 31); |
| 2975 | inst_base->idx = index; | 2903 | inst_base->idx = index; |
| 2976 | inst_base->br = NON_BRANCH; | 2904 | inst_base->br = NON_BRANCH; |
| 2977 | inst_base->load_r15 = 0; | 2905 | inst_base->load_r15 = 0; |
| 2978 | 2906 | ||
| 2979 | inst_cream->I = BIT(inst, 25); | 2907 | inst_cream->I = BIT(inst, 25); |
| 2980 | inst_cream->Rn = BITS(inst, 16, 19); | 2908 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2981 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2909 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 2982 | inst_cream->shtop_func = get_shtop(inst); | 2910 | inst_cream->shtop_func = get_shtop(inst); |
| 2983 | 2911 | ||
| 2984 | if (CHECK_RN) | 2912 | if (CHECK_RN) |
| 2985 | inst_base->load_r15 = 1; | 2913 | inst_base->load_r15 = 1; |
| 2986 | return inst_base; | 2914 | return inst_base; |
| 2987 | } | 2915 | } |
| 2988 | ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) | 2916 | ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) |
| 2989 | { | 2917 | { |
| 2990 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); | 2918 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); |
| 2991 | tst_inst *inst_cream = (tst_inst *)inst_base->component; | 2919 | tst_inst *inst_cream = (tst_inst *)inst_base->component; |
| 2992 | 2920 | ||
| 2993 | inst_base->cond = BITS(inst, 28, 31); | 2921 | inst_base->cond = BITS(inst, 28, 31); |
| 2994 | inst_base->idx = index; | 2922 | inst_base->idx = index; |
| 2995 | inst_base->br = NON_BRANCH; | 2923 | inst_base->br = NON_BRANCH; |
| 2996 | inst_base->load_r15 = 0; | 2924 | inst_base->load_r15 = 0; |
| 2997 | 2925 | ||
| 2998 | inst_cream->I = BIT(inst, 25); | 2926 | inst_cream->I = BIT(inst, 25); |
| 2999 | inst_cream->S = BIT(inst, 20); | 2927 | inst_cream->S = BIT(inst, 20); |
| 3000 | inst_cream->Rn = BITS(inst, 16, 19); | 2928 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3001 | inst_cream->Rd = BITS(inst, 12, 15); | 2929 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3002 | inst_cream->shifter_operand = BITS(inst, 0, 11); | 2930 | inst_cream->shifter_operand = BITS(inst, 0, 11); |
| 3003 | inst_cream->shtop_func = get_shtop(inst); | 2931 | inst_cream->shtop_func = get_shtop(inst); |
| 3004 | if (inst_cream->Rd == 15) { | 2932 | if (inst_cream->Rd == 15) { |
| 3005 | inst_base->br = INDIRECT_BRANCH; | 2933 | inst_base->br = INDIRECT_BRANCH; |
| 3006 | } | 2934 | } |
| 3007 | 2935 | ||
| 3008 | if (CHECK_RN) | 2936 | if (CHECK_RN) |
| 3009 | inst_base->load_r15 = 1; | 2937 | inst_base->load_r15 = 1; |
| 3010 | return inst_base; | 2938 | return inst_base; |
| 3011 | } | 2939 | } |
| 3012 | 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;} | 2940 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); } |
| 3013 | 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;} | 2941 | ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); } |
| 3014 | 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;} | 2942 | ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); } |
| 3015 | 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;} | 2943 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) |
| 3016 | 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;} | 2944 | { |
| 3017 | 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;} | 2945 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3018 | 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;} | 2946 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3019 | 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;} | 2947 | |
| 3020 | 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;} | 2948 | inst_base->cond = BITS(inst, 28, 31); |
| 3021 | 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;} | 2949 | inst_base->idx = index; |
| 2950 | inst_base->br = NON_BRANCH; | ||
| 2951 | inst_base->load_r15 = 0; | ||
| 2952 | |||
| 2953 | inst_cream->op1 = BITS(inst, 20, 21); | ||
| 2954 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 2955 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2956 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2957 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2958 | |||
| 2959 | return inst_base; | ||
| 2960 | } | ||
| 2961 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) | ||
| 2962 | { | ||
| 2963 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 2964 | } | ||
| 2965 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) | ||
| 2966 | { | ||
| 2967 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 2968 | } | ||
| 2969 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) | ||
| 2970 | { | ||
| 2971 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 2972 | } | ||
| 2973 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) | ||
| 2974 | { | ||
| 2975 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 2976 | } | ||
| 2977 | ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) | ||
| 2978 | { | ||
| 2979 | return INTERPRETER_TRANSLATE(uhadd8)(inst, index); | ||
| 2980 | } | ||
| 2981 | ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) | ||
| 2982 | { | ||
| 2983 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); | ||
| 2984 | umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; | ||
| 2985 | |||
| 2986 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2987 | inst_base->idx = index; | ||
| 2988 | inst_base->br = NON_BRANCH; | ||
| 2989 | inst_base->load_r15 = 0; | ||
| 2990 | |||
| 2991 | inst_cream->Rm = BITS(inst, 8, 11); | ||
| 2992 | inst_cream->Rn = BITS(inst, 0, 3); | ||
| 2993 | inst_cream->RdLo = BITS(inst, 12, 15); | ||
| 2994 | inst_cream->RdHi = BITS(inst, 16, 19); | ||
| 2995 | |||
| 2996 | if (CHECK_RM || CHECK_RN) | ||
| 2997 | inst_base->load_r15 = 1; | ||
| 2998 | |||
| 2999 | return inst_base; | ||
| 3000 | } | ||
| 3022 | ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) | 3001 | ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) |
| 3023 | { | 3002 | { |
| 3024 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); | 3003 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); |
| 3025 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 3004 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 3005 | |||
| 3006 | inst_base->cond = BITS(inst, 28, 31); | ||
| 3007 | inst_base->idx = index; | ||
| 3008 | inst_base->br = NON_BRANCH; | ||
| 3009 | inst_base->load_r15 = 0; | ||
| 3026 | 3010 | ||
| 3027 | inst_base->cond = BITS(inst, 28, 31); | 3011 | inst_cream->S = BIT(inst, 20); |
| 3028 | inst_base->idx = index; | 3012 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3029 | inst_base->br = NON_BRANCH; | 3013 | inst_cream->Rs = BITS(inst, 8, 11); |
| 3030 | inst_base->load_r15 = 0; | 3014 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 3015 | inst_cream->RdLo = BITS(inst, 12, 15); | ||
| 3031 | 3016 | ||
| 3032 | inst_cream->S = BIT(inst, 20); | 3017 | if (CHECK_RM || CHECK_RS) |
| 3033 | inst_cream->Rm = BITS(inst, 0, 3); | 3018 | inst_base->load_r15 = 1; |
| 3034 | inst_cream->Rs = BITS(inst, 8, 11); | ||
| 3035 | inst_cream->RdHi = BITS(inst, 16, 19); | ||
| 3036 | inst_cream->RdLo = BITS(inst, 12, 15); | ||
| 3037 | 3019 | ||
| 3038 | if (CHECK_RM || CHECK_RS) | 3020 | return inst_base; |
| 3039 | inst_base->load_r15 = 1; | ||
| 3040 | return inst_base; | ||
| 3041 | } | 3021 | } |
| 3042 | ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) | 3022 | ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) |
| 3043 | { | 3023 | { |
| 3044 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); | 3024 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); |
| 3045 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 3025 | umull_inst *inst_cream = (umull_inst *)inst_base->component; |
| 3046 | 3026 | ||
| 3047 | inst_base->cond = BITS(inst, 28, 31); | 3027 | inst_base->cond = BITS(inst, 28, 31); |
| 3048 | inst_base->idx = index; | 3028 | inst_base->idx = index; |
| 3049 | inst_base->br = NON_BRANCH; | 3029 | inst_base->br = NON_BRANCH; |
| 3050 | inst_base->load_r15 = 0; | 3030 | inst_base->load_r15 = 0; |
| 3051 | 3031 | ||
| 3052 | inst_cream->S = BIT(inst, 20); | 3032 | inst_cream->S = BIT(inst, 20); |
| 3053 | inst_cream->Rm = BITS(inst, 0, 3); | 3033 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3054 | inst_cream->Rs = BITS(inst, 8, 11); | 3034 | inst_cream->Rs = BITS(inst, 8, 11); |
| 3055 | inst_cream->RdHi = BITS(inst, 16, 19); | 3035 | inst_cream->RdHi = BITS(inst, 16, 19); |
| 3056 | inst_cream->RdLo = BITS(inst, 12, 15); | 3036 | inst_cream->RdLo = BITS(inst, 12, 15); |
| 3057 | 3037 | ||
| 3058 | if (CHECK_RM || CHECK_RS) | 3038 | if (CHECK_RM || CHECK_RS) |
| 3059 | inst_base->load_r15 = 1; | 3039 | inst_base->load_r15 = 1; |
| 3060 | return inst_base; | 3040 | return inst_base; |
| 3061 | } | 3041 | } |
| 3062 | 3042 | ||
| 3063 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) | 3043 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) |
| 3064 | { | 3044 | { |
| 3065 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); | 3045 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); |
| 3066 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; | 3046 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; |
| 3067 | 3047 | ||
| 3068 | inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); | 3048 | inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); |
| 3069 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | 3049 | |
| 3070 | inst_base->idx = index; | 3050 | inst_base->idx = index; |
| 3071 | inst_base->br = DIRECT_BRANCH; | 3051 | inst_base->br = DIRECT_BRANCH; |
| 3072 | return inst_base; | 3052 | |
| 3053 | return inst_base; | ||
| 3073 | } | 3054 | } |
| 3074 | 3055 | ||
| 3075 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) | 3056 | ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) |
| 3076 | { | 3057 | { |
| 3077 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); | 3058 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); |
| 3078 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; | 3059 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; |
| 3079 | 3060 | ||
| 3080 | inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); | 3061 | inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); |
| 3081 | inst_cream->cond = ((tinst >> 8) & 0xf); | 3062 | inst_cream->cond = ((tinst >> 8) & 0xf); |
| 3082 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond); | 3063 | inst_base->idx = index; |
| 3083 | inst_base->idx = index; | 3064 | inst_base->br = DIRECT_BRANCH; |
| 3084 | inst_base->br = DIRECT_BRANCH; | 3065 | |
| 3085 | return inst_base; | 3066 | return inst_base; |
| 3086 | } | 3067 | } |
| 3087 | 3068 | ||
| 3088 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) | 3069 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) |
| 3089 | { | 3070 | { |
| 3090 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); | 3071 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); |
| 3091 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; | 3072 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; |
| 3092 | 3073 | ||
| 3093 | inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); | 3074 | inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); |
| 3094 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | ||
| 3095 | 3075 | ||
| 3096 | inst_base->idx = index; | 3076 | inst_base->idx = index; |
| 3097 | inst_base->br = NON_BRANCH; | 3077 | inst_base->br = NON_BRANCH; |
| 3098 | return inst_base; | 3078 | return inst_base; |
| 3099 | } | 3079 | } |
| 3100 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) | 3080 | ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) |
| 3101 | { | 3081 | { |
| 3102 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); | 3082 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); |
| 3103 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; | 3083 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; |
| 3084 | |||
| 3085 | inst_cream->imm = (tinst & 0x07FF) << 1; | ||
| 3104 | 3086 | ||
| 3105 | inst_cream->imm = (tinst & 0x07FF) << 1; | 3087 | inst_base->idx = index; |
| 3106 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | 3088 | inst_base->br = DIRECT_BRANCH; |
| 3107 | inst_base->idx = index; | 3089 | return inst_base; |
| 3108 | inst_base->br = DIRECT_BRANCH; | ||
| 3109 | return inst_base; | ||
| 3110 | } | 3090 | } |
| 3111 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) | 3091 | ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) |
| 3112 | { | 3092 | { |
| 3113 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); | 3093 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); |
| 3114 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; | 3094 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; |
| 3115 | 3095 | ||
| 3116 | inst_cream->imm = (tinst & 0x07FF) << 1; | 3096 | inst_cream->imm = (tinst & 0x07FF) << 1; |
| 3117 | //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm); | 3097 | inst_cream->instr = tinst; |
| 3118 | inst_cream->instr = tinst; | 3098 | |
| 3119 | inst_base->idx = index; | 3099 | inst_base->idx = index; |
| 3120 | inst_base->br = DIRECT_BRANCH; | 3100 | inst_base->br = DIRECT_BRANCH; |
| 3121 | return inst_base; | 3101 | return inst_base; |
| 3122 | } | 3102 | } |
| 3123 | 3103 | ||
| 3124 | 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;} | 3104 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) |
| 3125 | 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;} | 3105 | { |
| 3126 | 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;} | 3106 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 3127 | 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;} | 3107 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 3128 | 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;} | 3108 | |
| 3129 | 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;} | 3109 | inst_base->cond = BITS(inst, 28, 31); |
| 3130 | 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;} | 3110 | inst_base->idx = index; |
| 3131 | 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;} | 3111 | inst_base->br = NON_BRANCH; |
| 3132 | 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;} | 3112 | inst_base->load_r15 = 0; |
| 3133 | 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;} | 3113 | |
| 3134 | 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;} | 3114 | inst_cream->Rm = BITS(inst, 0, 3); |
| 3135 | 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;} | 3115 | inst_cream->Rn = BITS(inst, 16, 19); |
| 3136 | 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;} | 3116 | inst_cream->Rd = BITS(inst, 12, 15); |
| 3137 | 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;} | 3117 | inst_cream->op1 = BITS(inst, 20, 21); |
| 3138 | 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;} | 3118 | inst_cream->op2 = BITS(inst, 5, 7); |
| 3119 | |||
| 3120 | return inst_base; | ||
| 3121 | } | ||
| 3122 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) | ||
| 3123 | { | ||
| 3124 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3125 | } | ||
| 3126 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) | ||
| 3127 | { | ||
| 3128 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3129 | } | ||
| 3130 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) | ||
| 3131 | { | ||
| 3132 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3133 | } | ||
| 3134 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) | ||
| 3135 | { | ||
| 3136 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3137 | } | ||
| 3138 | ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) | ||
| 3139 | { | ||
| 3140 | return INTERPRETER_TRANSLATE(uqadd8)(inst, index); | ||
| 3141 | } | ||
| 3142 | ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) | ||
| 3143 | { | ||
| 3144 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | ||
| 3145 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 3139 | 3146 | ||
| 3147 | inst_base->cond = BITS(inst, 28, 31); | ||
| 3148 | inst_base->idx = index; | ||
| 3149 | inst_base->br = NON_BRANCH; | ||
| 3150 | inst_base->load_r15 = 0; | ||
| 3140 | 3151 | ||
| 3152 | inst_cream->op1 = BITS(inst, 20, 24); | ||
| 3153 | inst_cream->op2 = BITS(inst, 5, 7); | ||
| 3154 | inst_cream->Rm = BITS(inst, 8, 11); | ||
| 3155 | inst_cream->Rn = BITS(inst, 0, 3); | ||
| 3156 | inst_cream->Ra = BITS(inst, 12, 15); | ||
| 3141 | 3157 | ||
| 3142 | /* Floating point VFPv3 structures and instructions */ | 3158 | return inst_base; |
| 3159 | } | ||
| 3160 | ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) | ||
| 3161 | { | ||
| 3162 | return INTERPRETER_TRANSLATE(usada8)(inst, index); | ||
| 3163 | } | ||
| 3164 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) | ||
| 3165 | { | ||
| 3166 | return INTERPRETER_TRANSLATE(ssat)(inst, index); | ||
| 3167 | } | ||
| 3168 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); } | ||
| 3169 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } | ||
| 3170 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } | ||
| 3171 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); } | ||
| 3172 | |||
| 3173 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) | ||
| 3174 | { | ||
| 3175 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); | ||
| 3176 | uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; | ||
| 3177 | |||
| 3178 | inst_base->cond = BITS(inst, 28, 31); | ||
| 3179 | inst_base->idx = index; | ||
| 3180 | inst_base->br = NON_BRANCH; | ||
| 3181 | inst_base->load_r15 = 0; | ||
| 3182 | |||
| 3183 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 3184 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 3185 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 3186 | inst_cream->rotate = BITS(inst, 10, 11); | ||
| 3187 | |||
| 3188 | return inst_base; | ||
| 3189 | } | ||
| 3190 | ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) | ||
| 3191 | { | ||
| 3192 | return INTERPRETER_TRANSLATE(uxtab16)(inst, index); | ||
| 3193 | } | ||
| 3194 | |||
| 3195 | // Floating point VFPv3 structures and instructions | ||
| 3143 | 3196 | ||
| 3144 | #define VFP_INTERPRETER_STRUCT | 3197 | #define VFP_INTERPRETER_STRUCT |
| 3145 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 3198 | #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 | |||
| 3149 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 3202 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" |
| 3150 | #undef VFP_INTERPRETER_TRANS | 3203 | #undef VFP_INTERPRETER_TRANS |
| 3151 | 3204 | ||
| 3152 | |||
| 3153 | |||
| 3154 | typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); | 3205 | typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int); |
| 3155 | 3206 | ||
| 3156 | const transop_fp_t arm_instruction_trans[] = { | 3207 | const transop_fp_t arm_instruction_trans[] = { |
| 3157 | #define VFP_INTERPRETER_TABLE | 3208 | INTERPRETER_TRANSLATE(vmla), |
| 3158 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 3209 | INTERPRETER_TRANSLATE(vmls), |
| 3159 | #undef VFP_INTERPRETER_TABLE | 3210 | INTERPRETER_TRANSLATE(vnmla), |
| 3160 | INTERPRETER_TRANSLATE(srs), | 3211 | INTERPRETER_TRANSLATE(vnmla), |
| 3161 | INTERPRETER_TRANSLATE(rfe), | 3212 | INTERPRETER_TRANSLATE(vnmls), |
| 3162 | INTERPRETER_TRANSLATE(bkpt), | 3213 | INTERPRETER_TRANSLATE(vnmul), |
| 3163 | INTERPRETER_TRANSLATE(blx), | 3214 | INTERPRETER_TRANSLATE(vmul), |
| 3164 | INTERPRETER_TRANSLATE(cps), | 3215 | INTERPRETER_TRANSLATE(vadd), |
| 3165 | INTERPRETER_TRANSLATE(pld), | 3216 | INTERPRETER_TRANSLATE(vsub), |
| 3166 | INTERPRETER_TRANSLATE(setend), | 3217 | INTERPRETER_TRANSLATE(vdiv), |
| 3167 | INTERPRETER_TRANSLATE(clrex), | 3218 | INTERPRETER_TRANSLATE(vmovi), |
| 3168 | INTERPRETER_TRANSLATE(rev16), | 3219 | INTERPRETER_TRANSLATE(vmovr), |
| 3169 | INTERPRETER_TRANSLATE(usad8), | 3220 | INTERPRETER_TRANSLATE(vabs), |
| 3170 | INTERPRETER_TRANSLATE(sxtb), | 3221 | INTERPRETER_TRANSLATE(vneg), |
| 3171 | INTERPRETER_TRANSLATE(uxtb), | 3222 | INTERPRETER_TRANSLATE(vsqrt), |
| 3172 | INTERPRETER_TRANSLATE(sxth), | 3223 | INTERPRETER_TRANSLATE(vcmp), |
| 3173 | INTERPRETER_TRANSLATE(sxtb16), | 3224 | INTERPRETER_TRANSLATE(vcmp2), |
| 3174 | INTERPRETER_TRANSLATE(uxth), | 3225 | INTERPRETER_TRANSLATE(vcvtbds), |
| 3175 | INTERPRETER_TRANSLATE(uxtb16), | 3226 | INTERPRETER_TRANSLATE(vcvtbff), |
| 3176 | INTERPRETER_TRANSLATE(cpy), | 3227 | INTERPRETER_TRANSLATE(vcvtbfi), |
| 3177 | INTERPRETER_TRANSLATE(uxtab), | 3228 | INTERPRETER_TRANSLATE(vmovbrs), |
| 3178 | INTERPRETER_TRANSLATE(ssub8), | 3229 | INTERPRETER_TRANSLATE(vmsr), |
| 3179 | INTERPRETER_TRANSLATE(shsub8), | 3230 | INTERPRETER_TRANSLATE(vmovbrc), |
| 3180 | INTERPRETER_TRANSLATE(ssubaddx), | 3231 | INTERPRETER_TRANSLATE(vmrs), |
| 3181 | INTERPRETER_TRANSLATE(strex), | 3232 | INTERPRETER_TRANSLATE(vmovbcr), |
| 3182 | INTERPRETER_TRANSLATE(strexb), | 3233 | INTERPRETER_TRANSLATE(vmovbrrss), |
| 3183 | INTERPRETER_TRANSLATE(swp), | 3234 | INTERPRETER_TRANSLATE(vmovbrrd), |
| 3184 | INTERPRETER_TRANSLATE(swpb), | 3235 | INTERPRETER_TRANSLATE(vstr), |
| 3185 | INTERPRETER_TRANSLATE(ssub16), | 3236 | INTERPRETER_TRANSLATE(vpush), |
| 3186 | INTERPRETER_TRANSLATE(ssat16), | 3237 | INTERPRETER_TRANSLATE(vstm), |
| 3187 | INTERPRETER_TRANSLATE(shsubaddx), | 3238 | INTERPRETER_TRANSLATE(vpop), |
| 3188 | INTERPRETER_TRANSLATE(qsubaddx), | 3239 | INTERPRETER_TRANSLATE(vldr), |
| 3189 | INTERPRETER_TRANSLATE(shaddsubx), | 3240 | INTERPRETER_TRANSLATE(vldm), |
| 3190 | INTERPRETER_TRANSLATE(shadd8), | 3241 | |
| 3191 | INTERPRETER_TRANSLATE(shadd16), | 3242 | INTERPRETER_TRANSLATE(srs), |
| 3192 | INTERPRETER_TRANSLATE(sel), | 3243 | INTERPRETER_TRANSLATE(rfe), |
| 3193 | INTERPRETER_TRANSLATE(saddsubx), | 3244 | INTERPRETER_TRANSLATE(bkpt), |
| 3194 | INTERPRETER_TRANSLATE(sadd8), | 3245 | INTERPRETER_TRANSLATE(blx), |
| 3195 | INTERPRETER_TRANSLATE(sadd16), | 3246 | INTERPRETER_TRANSLATE(cps), |
| 3196 | INTERPRETER_TRANSLATE(shsub16), | 3247 | INTERPRETER_TRANSLATE(pld), |
| 3197 | INTERPRETER_TRANSLATE(umaal), | 3248 | INTERPRETER_TRANSLATE(setend), |
| 3198 | INTERPRETER_TRANSLATE(uxtab16), | 3249 | INTERPRETER_TRANSLATE(clrex), |
| 3199 | INTERPRETER_TRANSLATE(usubaddx), | 3250 | INTERPRETER_TRANSLATE(rev16), |
| 3200 | INTERPRETER_TRANSLATE(usub8), | 3251 | INTERPRETER_TRANSLATE(usad8), |
| 3201 | INTERPRETER_TRANSLATE(usub16), | 3252 | INTERPRETER_TRANSLATE(sxtb), |
| 3202 | INTERPRETER_TRANSLATE(usat16), | 3253 | INTERPRETER_TRANSLATE(uxtb), |
| 3203 | INTERPRETER_TRANSLATE(usada8), | 3254 | INTERPRETER_TRANSLATE(sxth), |
| 3204 | INTERPRETER_TRANSLATE(uqsubaddx), | 3255 | INTERPRETER_TRANSLATE(sxtb16), |
| 3205 | INTERPRETER_TRANSLATE(uqsub8), | 3256 | INTERPRETER_TRANSLATE(uxth), |
| 3206 | INTERPRETER_TRANSLATE(uqsub16), | 3257 | INTERPRETER_TRANSLATE(uxtb16), |
| 3207 | INTERPRETER_TRANSLATE(uqaddsubx), | 3258 | INTERPRETER_TRANSLATE(cpy), |
| 3208 | INTERPRETER_TRANSLATE(uqadd8), | 3259 | INTERPRETER_TRANSLATE(uxtab), |
| 3209 | INTERPRETER_TRANSLATE(uqadd16), | 3260 | INTERPRETER_TRANSLATE(ssub8), |
| 3210 | INTERPRETER_TRANSLATE(sxtab), | 3261 | INTERPRETER_TRANSLATE(shsub8), |
| 3211 | INTERPRETER_TRANSLATE(uhsubaddx), | 3262 | INTERPRETER_TRANSLATE(ssubaddx), |
| 3212 | INTERPRETER_TRANSLATE(uhsub8), | 3263 | INTERPRETER_TRANSLATE(strex), |
| 3213 | INTERPRETER_TRANSLATE(uhsub16), | 3264 | INTERPRETER_TRANSLATE(strexb), |
| 3214 | INTERPRETER_TRANSLATE(uhaddsubx), | 3265 | INTERPRETER_TRANSLATE(swp), |
| 3215 | INTERPRETER_TRANSLATE(uhadd8), | 3266 | INTERPRETER_TRANSLATE(swpb), |
| 3216 | INTERPRETER_TRANSLATE(uhadd16), | 3267 | INTERPRETER_TRANSLATE(ssub16), |
| 3217 | INTERPRETER_TRANSLATE(uaddsubx), | 3268 | INTERPRETER_TRANSLATE(ssat16), |
| 3218 | INTERPRETER_TRANSLATE(uadd8), | 3269 | INTERPRETER_TRANSLATE(shsubaddx), |
| 3219 | INTERPRETER_TRANSLATE(uadd16), | 3270 | INTERPRETER_TRANSLATE(qsubaddx), |
| 3220 | INTERPRETER_TRANSLATE(sxtah), | 3271 | INTERPRETER_TRANSLATE(shaddsubx), |
| 3221 | INTERPRETER_TRANSLATE(sxtab16), | 3272 | INTERPRETER_TRANSLATE(shadd8), |
| 3222 | INTERPRETER_TRANSLATE(qadd8), | 3273 | INTERPRETER_TRANSLATE(shadd16), |
| 3223 | INTERPRETER_TRANSLATE(bxj), | 3274 | INTERPRETER_TRANSLATE(sel), |
| 3224 | INTERPRETER_TRANSLATE(clz), | 3275 | INTERPRETER_TRANSLATE(saddsubx), |
| 3225 | INTERPRETER_TRANSLATE(uxtah), | 3276 | INTERPRETER_TRANSLATE(sadd8), |
| 3226 | INTERPRETER_TRANSLATE(bx), | 3277 | INTERPRETER_TRANSLATE(sadd16), |
| 3227 | INTERPRETER_TRANSLATE(rev), | 3278 | INTERPRETER_TRANSLATE(shsub16), |
| 3228 | INTERPRETER_TRANSLATE(blx), | 3279 | INTERPRETER_TRANSLATE(umaal), |
| 3229 | INTERPRETER_TRANSLATE(revsh), | 3280 | INTERPRETER_TRANSLATE(uxtab16), |
| 3230 | INTERPRETER_TRANSLATE(qadd), | 3281 | INTERPRETER_TRANSLATE(usubaddx), |
| 3231 | INTERPRETER_TRANSLATE(qadd16), | 3282 | INTERPRETER_TRANSLATE(usub8), |
| 3232 | INTERPRETER_TRANSLATE(qaddsubx), | 3283 | INTERPRETER_TRANSLATE(usub16), |
| 3233 | INTERPRETER_TRANSLATE(ldrex), | 3284 | INTERPRETER_TRANSLATE(usat16), |
| 3234 | INTERPRETER_TRANSLATE(qdadd), | 3285 | INTERPRETER_TRANSLATE(usada8), |
| 3235 | INTERPRETER_TRANSLATE(qdsub), | 3286 | INTERPRETER_TRANSLATE(uqsubaddx), |
| 3236 | INTERPRETER_TRANSLATE(qsub), | 3287 | INTERPRETER_TRANSLATE(uqsub8), |
| 3237 | INTERPRETER_TRANSLATE(ldrexb), | 3288 | INTERPRETER_TRANSLATE(uqsub16), |
| 3238 | INTERPRETER_TRANSLATE(qsub8), | 3289 | INTERPRETER_TRANSLATE(uqaddsubx), |
| 3239 | INTERPRETER_TRANSLATE(qsub16), | 3290 | INTERPRETER_TRANSLATE(uqadd8), |
| 3240 | INTERPRETER_TRANSLATE(smuad), | 3291 | INTERPRETER_TRANSLATE(uqadd16), |
| 3241 | INTERPRETER_TRANSLATE(smmul), | 3292 | INTERPRETER_TRANSLATE(sxtab), |
| 3242 | INTERPRETER_TRANSLATE(smusd), | 3293 | INTERPRETER_TRANSLATE(uhsubaddx), |
| 3243 | INTERPRETER_TRANSLATE(smlsd), | 3294 | INTERPRETER_TRANSLATE(uhsub8), |
| 3244 | INTERPRETER_TRANSLATE(smlsld), | 3295 | INTERPRETER_TRANSLATE(uhsub16), |
| 3245 | INTERPRETER_TRANSLATE(smmla), | 3296 | INTERPRETER_TRANSLATE(uhaddsubx), |
| 3246 | INTERPRETER_TRANSLATE(smmls), | 3297 | INTERPRETER_TRANSLATE(uhadd8), |
| 3247 | INTERPRETER_TRANSLATE(smlald), | 3298 | INTERPRETER_TRANSLATE(uhadd16), |
| 3248 | INTERPRETER_TRANSLATE(smlad), | 3299 | INTERPRETER_TRANSLATE(uaddsubx), |
| 3249 | INTERPRETER_TRANSLATE(smlaw), | 3300 | INTERPRETER_TRANSLATE(uadd8), |
| 3250 | INTERPRETER_TRANSLATE(smulw), | 3301 | INTERPRETER_TRANSLATE(uadd16), |
| 3251 | INTERPRETER_TRANSLATE(pkhtb), | 3302 | INTERPRETER_TRANSLATE(sxtah), |
| 3252 | INTERPRETER_TRANSLATE(pkhbt), | 3303 | INTERPRETER_TRANSLATE(sxtab16), |
| 3253 | INTERPRETER_TRANSLATE(smul), | 3304 | INTERPRETER_TRANSLATE(qadd8), |
| 3254 | INTERPRETER_TRANSLATE(smlalxy), | 3305 | INTERPRETER_TRANSLATE(bxj), |
| 3255 | INTERPRETER_TRANSLATE(smla), | 3306 | INTERPRETER_TRANSLATE(clz), |
| 3256 | INTERPRETER_TRANSLATE(mcrr), | 3307 | INTERPRETER_TRANSLATE(uxtah), |
| 3257 | INTERPRETER_TRANSLATE(mrrc), | 3308 | INTERPRETER_TRANSLATE(bx), |
| 3258 | INTERPRETER_TRANSLATE(cmp), | 3309 | INTERPRETER_TRANSLATE(rev), |
| 3259 | INTERPRETER_TRANSLATE(tst), | 3310 | INTERPRETER_TRANSLATE(blx), |
| 3260 | INTERPRETER_TRANSLATE(teq), | 3311 | INTERPRETER_TRANSLATE(revsh), |
| 3261 | INTERPRETER_TRANSLATE(cmn), | 3312 | INTERPRETER_TRANSLATE(qadd), |
| 3262 | INTERPRETER_TRANSLATE(smull), | 3313 | INTERPRETER_TRANSLATE(qadd16), |
| 3263 | INTERPRETER_TRANSLATE(umull), | 3314 | INTERPRETER_TRANSLATE(qaddsubx), |
| 3264 | INTERPRETER_TRANSLATE(umlal), | 3315 | INTERPRETER_TRANSLATE(ldrex), |
| 3265 | INTERPRETER_TRANSLATE(smlal), | 3316 | INTERPRETER_TRANSLATE(qdadd), |
| 3266 | INTERPRETER_TRANSLATE(mul), | 3317 | INTERPRETER_TRANSLATE(qdsub), |
| 3267 | INTERPRETER_TRANSLATE(mla), | 3318 | INTERPRETER_TRANSLATE(qsub), |
| 3268 | INTERPRETER_TRANSLATE(ssat), | 3319 | INTERPRETER_TRANSLATE(ldrexb), |
| 3269 | INTERPRETER_TRANSLATE(usat), | 3320 | INTERPRETER_TRANSLATE(qsub8), |
| 3270 | INTERPRETER_TRANSLATE(mrs), | 3321 | INTERPRETER_TRANSLATE(qsub16), |
| 3271 | INTERPRETER_TRANSLATE(msr), | 3322 | INTERPRETER_TRANSLATE(smuad), |
| 3272 | INTERPRETER_TRANSLATE(and), | 3323 | INTERPRETER_TRANSLATE(smmul), |
| 3273 | INTERPRETER_TRANSLATE(bic), | 3324 | INTERPRETER_TRANSLATE(smusd), |
| 3274 | INTERPRETER_TRANSLATE(ldm), | 3325 | INTERPRETER_TRANSLATE(smlsd), |
| 3275 | INTERPRETER_TRANSLATE(eor), | 3326 | INTERPRETER_TRANSLATE(smlsld), |
| 3276 | INTERPRETER_TRANSLATE(add), | 3327 | INTERPRETER_TRANSLATE(smmla), |
| 3277 | INTERPRETER_TRANSLATE(rsb), | 3328 | INTERPRETER_TRANSLATE(smmls), |
| 3278 | INTERPRETER_TRANSLATE(rsc), | 3329 | INTERPRETER_TRANSLATE(smlald), |
| 3279 | INTERPRETER_TRANSLATE(sbc), | 3330 | INTERPRETER_TRANSLATE(smlad), |
| 3280 | INTERPRETER_TRANSLATE(adc), | 3331 | INTERPRETER_TRANSLATE(smlaw), |
| 3281 | INTERPRETER_TRANSLATE(sub), | 3332 | INTERPRETER_TRANSLATE(smulw), |
| 3282 | INTERPRETER_TRANSLATE(orr), | 3333 | INTERPRETER_TRANSLATE(pkhtb), |
| 3283 | INTERPRETER_TRANSLATE(mvn), | 3334 | INTERPRETER_TRANSLATE(pkhbt), |
| 3284 | INTERPRETER_TRANSLATE(mov), | 3335 | INTERPRETER_TRANSLATE(smul), |
| 3285 | INTERPRETER_TRANSLATE(stm), | 3336 | INTERPRETER_TRANSLATE(smlalxy), |
| 3286 | INTERPRETER_TRANSLATE(ldm), | 3337 | INTERPRETER_TRANSLATE(smla), |
| 3287 | INTERPRETER_TRANSLATE(ldrsh), | 3338 | INTERPRETER_TRANSLATE(mcrr), |
| 3288 | INTERPRETER_TRANSLATE(stm), | 3339 | INTERPRETER_TRANSLATE(mrrc), |
| 3289 | INTERPRETER_TRANSLATE(ldm), | 3340 | INTERPRETER_TRANSLATE(cmp), |
| 3290 | INTERPRETER_TRANSLATE(ldrsb), | 3341 | INTERPRETER_TRANSLATE(tst), |
| 3291 | INTERPRETER_TRANSLATE(strd), | 3342 | INTERPRETER_TRANSLATE(teq), |
| 3292 | INTERPRETER_TRANSLATE(ldrh), | 3343 | INTERPRETER_TRANSLATE(cmn), |
| 3293 | INTERPRETER_TRANSLATE(strh), | 3344 | INTERPRETER_TRANSLATE(smull), |
| 3294 | INTERPRETER_TRANSLATE(ldrd), | 3345 | INTERPRETER_TRANSLATE(umull), |
| 3295 | INTERPRETER_TRANSLATE(strt), | 3346 | INTERPRETER_TRANSLATE(umlal), |
| 3296 | INTERPRETER_TRANSLATE(strbt), | 3347 | INTERPRETER_TRANSLATE(smlal), |
| 3297 | INTERPRETER_TRANSLATE(ldrbt), | 3348 | INTERPRETER_TRANSLATE(mul), |
| 3298 | INTERPRETER_TRANSLATE(ldrt), | 3349 | INTERPRETER_TRANSLATE(mla), |
| 3299 | INTERPRETER_TRANSLATE(mrc), | 3350 | INTERPRETER_TRANSLATE(ssat), |
| 3300 | INTERPRETER_TRANSLATE(mcr), | 3351 | INTERPRETER_TRANSLATE(usat), |
| 3301 | INTERPRETER_TRANSLATE(msr), | 3352 | INTERPRETER_TRANSLATE(mrs), |
| 3302 | INTERPRETER_TRANSLATE(ldrb), | 3353 | INTERPRETER_TRANSLATE(msr), |
| 3303 | INTERPRETER_TRANSLATE(strb), | 3354 | INTERPRETER_TRANSLATE(and), |
| 3304 | INTERPRETER_TRANSLATE(ldr), | 3355 | INTERPRETER_TRANSLATE(bic), |
| 3305 | INTERPRETER_TRANSLATE(ldrcond), | 3356 | INTERPRETER_TRANSLATE(ldm), |
| 3306 | INTERPRETER_TRANSLATE(str), | 3357 | INTERPRETER_TRANSLATE(eor), |
| 3307 | INTERPRETER_TRANSLATE(cdp), | 3358 | INTERPRETER_TRANSLATE(add), |
| 3308 | INTERPRETER_TRANSLATE(stc), | 3359 | INTERPRETER_TRANSLATE(rsb), |
| 3309 | INTERPRETER_TRANSLATE(ldc), | 3360 | INTERPRETER_TRANSLATE(rsc), |
| 3310 | INTERPRETER_TRANSLATE(swi), | 3361 | INTERPRETER_TRANSLATE(sbc), |
| 3311 | INTERPRETER_TRANSLATE(bbl), | 3362 | INTERPRETER_TRANSLATE(adc), |
| 3312 | /* All the thumb instructions should be placed the end of table */ | 3363 | INTERPRETER_TRANSLATE(sub), |
| 3313 | INTERPRETER_TRANSLATE(b_2_thumb), | 3364 | INTERPRETER_TRANSLATE(orr), |
| 3314 | INTERPRETER_TRANSLATE(b_cond_thumb), | 3365 | INTERPRETER_TRANSLATE(mvn), |
| 3315 | INTERPRETER_TRANSLATE(bl_1_thumb), | 3366 | INTERPRETER_TRANSLATE(mov), |
| 3316 | INTERPRETER_TRANSLATE(bl_2_thumb), | 3367 | INTERPRETER_TRANSLATE(stm), |
| 3317 | INTERPRETER_TRANSLATE(blx_1_thumb) | 3368 | INTERPRETER_TRANSLATE(ldm), |
| 3369 | INTERPRETER_TRANSLATE(ldrsh), | ||
| 3370 | INTERPRETER_TRANSLATE(stm), | ||
| 3371 | INTERPRETER_TRANSLATE(ldm), | ||
| 3372 | INTERPRETER_TRANSLATE(ldrsb), | ||
| 3373 | INTERPRETER_TRANSLATE(strd), | ||
| 3374 | INTERPRETER_TRANSLATE(ldrh), | ||
| 3375 | INTERPRETER_TRANSLATE(strh), | ||
| 3376 | INTERPRETER_TRANSLATE(ldrd), | ||
| 3377 | INTERPRETER_TRANSLATE(strt), | ||
| 3378 | INTERPRETER_TRANSLATE(strbt), | ||
| 3379 | INTERPRETER_TRANSLATE(ldrbt), | ||
| 3380 | INTERPRETER_TRANSLATE(ldrt), | ||
| 3381 | INTERPRETER_TRANSLATE(mrc), | ||
| 3382 | INTERPRETER_TRANSLATE(mcr), | ||
| 3383 | INTERPRETER_TRANSLATE(msr), | ||
| 3384 | INTERPRETER_TRANSLATE(ldrb), | ||
| 3385 | INTERPRETER_TRANSLATE(strb), | ||
| 3386 | INTERPRETER_TRANSLATE(ldr), | ||
| 3387 | INTERPRETER_TRANSLATE(ldrcond), | ||
| 3388 | INTERPRETER_TRANSLATE(str), | ||
| 3389 | INTERPRETER_TRANSLATE(cdp), | ||
| 3390 | INTERPRETER_TRANSLATE(stc), | ||
| 3391 | INTERPRETER_TRANSLATE(ldc), | ||
| 3392 | INTERPRETER_TRANSLATE(swi), | ||
| 3393 | INTERPRETER_TRANSLATE(bbl), | ||
| 3394 | // All the thumb instructions should be placed the end of table | ||
| 3395 | INTERPRETER_TRANSLATE(b_2_thumb), | ||
| 3396 | INTERPRETER_TRANSLATE(b_cond_thumb), | ||
| 3397 | INTERPRETER_TRANSLATE(bl_1_thumb), | ||
| 3398 | INTERPRETER_TRANSLATE(bl_2_thumb), | ||
| 3399 | INTERPRETER_TRANSLATE(blx_1_thumb) | ||
| 3318 | }; | 3400 | }; |
| 3319 | 3401 | ||
| 3320 | typedef map<unsigned int, int> bb_map; | 3402 | typedef std::unordered_map<u32, int> bb_map; |
| 3321 | bb_map CreamCache[65536]; | 3403 | bb_map CreamCache; |
| 3322 | bb_map ProfileCache[65536]; | ||
| 3323 | |||
| 3324 | //#define USE_DUMMY_CACHE | ||
| 3325 | 3404 | ||
| 3326 | #ifdef USE_DUMMY_CACHE | 3405 | void insert_bb(unsigned int addr, int start) { |
| 3327 | unsigned int DummyCache[0x100000]; | 3406 | CreamCache[addr] = start; |
| 3328 | #endif | ||
| 3329 | |||
| 3330 | #define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536) | ||
| 3331 | void insert_bb(unsigned int addr, int start) | ||
| 3332 | { | ||
| 3333 | #ifdef USE_DUMMY_CACHE | ||
| 3334 | DummyCache[addr] = start; | ||
| 3335 | #else | ||
| 3336 | // CreamCache[addr] = start; | ||
| 3337 | CreamCache[HASH(addr)][addr] = start; | ||
| 3338 | #endif | ||
| 3339 | } | 3407 | } |
| 3340 | 3408 | ||
| 3341 | #define TRANS_THRESHOLD 65000 | 3409 | #define TRANS_THRESHOLD 65000 |
| 3342 | int find_bb(unsigned int addr, int &start) | 3410 | int find_bb(unsigned int addr, int &start) { |
| 3343 | { | 3411 | int ret = -1; |
| 3344 | int ret = -1; | 3412 | bb_map::const_iterator it = CreamCache.find(addr); |
| 3345 | #ifdef USE_DUMMY_CACHE | 3413 | if (it != CreamCache.end()) { |
| 3346 | start = DummyCache[addr]; | 3414 | start = static_cast<int>(it->second); |
| 3347 | if (start) { | 3415 | ret = 0; |
| 3348 | ret = 0; | 3416 | } else { |
| 3349 | } else | 3417 | ret = -1; |
| 3350 | ret = -1; | 3418 | } |
| 3351 | #else | 3419 | return ret; |
| 3352 | bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr); | ||
| 3353 | if (it != CreamCache[HASH(addr)].end()) { | ||
| 3354 | start = static_cast<int>(it->second); | ||
| 3355 | ret = 0; | ||
| 3356 | #if HYBRID_MODE | ||
| 3357 | #if PROFILE | ||
| 3358 | #else | ||
| 3359 | /* increase the bb counter */ | ||
| 3360 | if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){ | ||
| 3361 | push_to_compiled(cpu, addr); | ||
| 3362 | } | ||
| 3363 | #endif | ||
| 3364 | #endif | ||
| 3365 | } else { | ||
| 3366 | ret = -1; | ||
| 3367 | } | ||
| 3368 | #endif | ||
| 3369 | return ret; | ||
| 3370 | } | 3420 | } |
| 3371 | 3421 | ||
| 3372 | |||
| 3373 | enum { | 3422 | enum { |
| 3374 | FETCH_SUCCESS, | 3423 | FETCH_SUCCESS, |
| 3375 | FETCH_FAILURE | 3424 | FETCH_FAILURE |
| 3376 | }; | 3425 | }; |
| 3426 | |||
| 3377 | 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){ | 3427 | 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){ |
| 3378 | /* Check if in Thumb mode. */ | 3428 | // Check if in Thumb mode |
| 3379 | tdstate ret; | 3429 | tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); |
| 3380 | ret = thumb_translate (addr, inst, arm_inst, inst_size); | 3430 | if(ret == t_branch){ |
| 3381 | if(ret == t_branch){ | 3431 | // TODO: FIXME, endian should be judged |
| 3382 | /* FIXME, endian should be judged */ | 3432 | uint32 tinstr; |
| 3383 | uint32 tinstr; | 3433 | if((addr & 0x3) != 0) |
| 3384 | if((addr & 0x3) != 0) | 3434 | tinstr = inst >> 16; |
| 3385 | tinstr = inst >> 16; | 3435 | else |
| 3386 | else | 3436 | tinstr = inst & 0xFFFF; |
| 3387 | tinstr = inst & 0xFFFF; | 3437 | |
| 3388 | 3438 | int inst_index; | |
| 3389 | //tinstr = inst & 0xFFFF; | 3439 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); |
| 3390 | int inst_index; | 3440 | |
| 3391 | /* table_length */ | 3441 | switch((tinstr & 0xF800) >> 11){ |
| 3392 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); | 3442 | case 26: |
| 3393 | 3443 | case 27: | |
| 3394 | switch((tinstr & 0xF800) >> 11){ | 3444 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ |
| 3395 | /* we will translate the thumb instruction directly here */ | 3445 | uint32 cond = (tinstr & 0x0F00) >> 8; |
| 3396 | /* we will translate the thumb instruction directly here */ | 3446 | inst_index = table_length - 4; |
| 3397 | case 26: | 3447 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3398 | case 27: | 3448 | } else { |
| 3399 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ | 3449 | LOG_ERROR(Core_ARM11, "thumb decoder error"); |
| 3400 | uint32 cond = (tinstr & 0x0F00) >> 8; | 3450 | } |
| 3401 | inst_index = table_length - 4; | 3451 | break; |
| 3402 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); | 3452 | case 28: |
| 3403 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3453 | // Branch 2, unconditional branch |
| 3404 | } | 3454 | inst_index = table_length - 5; |
| 3405 | else{ | 3455 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3406 | /* something wrong */ | 3456 | break; |
| 3407 | DEBUG_LOG(ARM11, "In %s, thumb decoder error\n", __FUNCTION__); | 3457 | |
| 3408 | } | 3458 | case 8: |
| 3409 | break; | 3459 | case 29: |
| 3410 | case 28: | 3460 | // For BLX 1 thumb instruction |
| 3411 | /* Branch 2, unconditional branch */ | 3461 | inst_index = table_length - 1; |
| 3412 | inst_index = table_length - 5; | 3462 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3413 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index); | 3463 | break; |
| 3414 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3464 | case 30: |
| 3415 | break; | 3465 | // For BL 1 thumb instruction |
| 3416 | 3466 | inst_index = table_length - 3; | |
| 3417 | case 8: | 3467 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3418 | case 29: | 3468 | break; |
| 3419 | /* For BLX 1 thumb instruction*/ | 3469 | case 31: |
| 3420 | inst_index = table_length - 1; | 3470 | // For BL 2 thumb instruction |
| 3421 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); | 3471 | inst_index = table_length - 2; |
| 3422 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3472 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3423 | break; | 3473 | break; |
| 3424 | case 30: | 3474 | default: |
| 3425 | /* For BL 1 thumb instruction*/ | 3475 | ret = t_undefined; |
| 3426 | inst_index = table_length - 3; | 3476 | break; |
| 3427 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); | 3477 | } |
| 3428 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3478 | } |
| 3429 | break; | 3479 | return ret; |
| 3430 | case 31: | ||
| 3431 | /* For BL 2 thumb instruction*/ | ||
| 3432 | inst_index = table_length - 2; | ||
| 3433 | //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc); | ||
| 3434 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | ||
| 3435 | break; | ||
| 3436 | default: | ||
| 3437 | ret = t_undefined; | ||
| 3438 | break; | ||
| 3439 | } | ||
| 3440 | } | ||
| 3441 | return ret; | ||
| 3442 | } | ||
| 3443 | |||
| 3444 | #if 0 | ||
| 3445 | int FetchInst(cpu_t *core, unsigned int &inst) | ||
| 3446 | { | ||
| 3447 | //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); | ||
| 3448 | arm_processor *cpu = (arm_processor *)(core->cpu_data->obj); | ||
| 3449 | // fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32); | ||
| 3450 | fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32); | ||
| 3451 | if (!core->is_user_mode) { | ||
| 3452 | if (fault) { | ||
| 3453 | cpu->abortSig = true; | ||
| 3454 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3455 | cpu->AbortAddr = cpu->translate_pc; | ||
| 3456 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3457 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc; | ||
| 3458 | return FETCH_FAILURE; | ||
| 3459 | } | ||
| 3460 | } | ||
| 3461 | return FETCH_SUCCESS; | ||
| 3462 | } | 3480 | } |
| 3463 | #endif | ||
| 3464 | 3481 | ||
| 3465 | unsigned int *InstLength; | 3482 | unsigned int *InstLength; |
| 3466 | 3483 | ||
| 3467 | enum { | 3484 | enum { |
| 3468 | KEEP_GOING, | 3485 | KEEP_GOING, |
| 3469 | FETCH_EXCEPTION | 3486 | FETCH_EXCEPTION |
| 3470 | }; | 3487 | }; |
| 3471 | 3488 | ||
| 3472 | typedef struct instruction_set_encoding_item ISEITEM; | 3489 | typedef struct instruction_set_encoding_item ISEITEM; |
| @@ -3475,289 +3492,148 @@ extern const ISEITEM arm_instruction[]; | |||
| 3475 | 3492 | ||
| 3476 | vector<uint64_t> code_page_set; | 3493 | vector<uint64_t> code_page_set; |
| 3477 | 3494 | ||
| 3478 | void flush_bb(uint32_t addr) | 3495 | void flush_bb(uint32_t addr) { |
| 3479 | { | 3496 | bb_map::iterator it; |
| 3480 | bb_map::iterator it; | 3497 | uint32_t start; |
| 3481 | uint32_t start; | 3498 | |
| 3482 | 3499 | addr &= 0xfffff000; | |
| 3483 | addr &= 0xfffff000; | 3500 | for (it = CreamCache.begin(); it != CreamCache.end(); ) { |
| 3484 | for (int i = 0; i < 65536; i ++) { | 3501 | start = static_cast<uint32_t>(it->first); |
| 3485 | for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) { | 3502 | start &= 0xfffff000; |
| 3486 | start = static_cast<uint32_t>(it->first); | 3503 | if (start == addr) { |
| 3487 | //start = (start >> 12) << 12; | 3504 | CreamCache.erase(it++); |
| 3488 | start &= 0xfffff000; | 3505 | } else |
| 3489 | if (start == addr) { | 3506 | ++it; |
| 3490 | //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); | 3507 | } |
| 3491 | CreamCache[i].erase(it ++); | 3508 | } |
| 3492 | } else | ||
| 3493 | ++it; | ||
| 3494 | } | ||
| 3495 | } | ||
| 3496 | |||
| 3497 | for (int i = 0; i < 65536; i ++) { | ||
| 3498 | for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) { | ||
| 3499 | start = static_cast<uint32_t>(it->first); | ||
| 3500 | //start = (start >> 12) << 12; | ||
| 3501 | start &= 0xfffff000; | ||
| 3502 | if (start == addr) { | ||
| 3503 | //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); | ||
| 3504 | ProfileCache[i].erase(it ++); | ||
| 3505 | } else | ||
| 3506 | ++it; | ||
| 3507 | } | ||
| 3508 | } | ||
| 3509 | |||
| 3510 | //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr); | ||
| 3511 | } | ||
| 3512 | |||
| 3513 | //static uint32_t get_bank_addr(void *addr) | ||
| 3514 | //{ | ||
| 3515 | // uint64_t address = (uint64_t)addr; | ||
| 3516 | // uint64_t bank0 = get_dma_addr(BANK0_START); | ||
| 3517 | // if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) { | ||
| 3518 | // //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr); | ||
| 3519 | // return ((uint64_t)addr - bank0) + BANK0_START; | ||
| 3520 | // } | ||
| 3521 | // return 0; | ||
| 3522 | //} | ||
| 3523 | |||
| 3524 | /* shenoubang add win32 2012-6-12 */ | ||
| 3525 | //#ifndef __WIN32__ | ||
| 3526 | //static void flush_code_cache(int signal_number, siginfo_t *si, void *unused) | ||
| 3527 | //{ | ||
| 3528 | // DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr); | ||
| 3529 | // uint64_t addr = (uint64_t)si->si_addr; | ||
| 3530 | // addr = (addr >> 12) << 12; | ||
| 3531 | // skyeye_backtrace(); | ||
| 3532 | // #if 0 | ||
| 3533 | // if (addr == 0) { | ||
| 3534 | // return; | ||
| 3535 | // } | ||
| 3536 | // const vector<uint64_t>::iterator it = find(code_page_set.begin(), | ||
| 3537 | // code_page_set.end(), | ||
| 3538 | // (uint64_t)addr); | ||
| 3539 | // if (it != code_page_set.end()) { | ||
| 3540 | // code_page_set.erase(it); | ||
| 3541 | // } | ||
| 3542 | // mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE); | ||
| 3543 | // //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr); | ||
| 3544 | // uint32_t phys_addr = get_bank_addr((void *)addr); | ||
| 3545 | //// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr); | ||
| 3546 | // flush_bb(phys_addr); | ||
| 3547 | // flush_bb(phys_addr + 4096); | ||
| 3548 | //#if HYBRID_MODE | ||
| 3549 | // /* flush the translated BB of dyncom */ | ||
| 3550 | // clear_translated_cache(phys_addr); | ||
| 3551 | //#endif | ||
| 3552 | // #endif | ||
| 3553 | //} | ||
| 3554 | //#endif /* shenoubang */ | ||
| 3555 | |||
| 3556 | //void protect_code_page(uint32_t addr) | ||
| 3557 | //{ | ||
| 3558 | // void *mem_ptr = (void *)get_dma_addr(addr); | ||
| 3559 | // mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL); | ||
| 3560 | // | ||
| 3561 | // const vector<uint64_t>::iterator it = find(code_page_set.begin(), | ||
| 3562 | // code_page_set.end(), | ||
| 3563 | // (uint64_t)mem_ptr); | ||
| 3564 | // if (it != code_page_set.end()) { | ||
| 3565 | // return; | ||
| 3566 | // } | ||
| 3567 | // //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr); | ||
| 3568 | // /* shenoubang add win32 2012-6-12 */ | ||
| 3569 | //#ifndef __WIN32__ | ||
| 3570 | // struct sigaction sa; | ||
| 3571 | // | ||
| 3572 | // memset(&sa, 0, sizeof(sa)); | ||
| 3573 | // sa.sa_flags = SA_RESTART | SA_SIGINFO; | ||
| 3574 | // sa.sa_sigaction = &flush_code_cache; | ||
| 3575 | // sigaction(SIGSEGV, &sa, NULL); | ||
| 3576 | // | ||
| 3577 | // //mprotect(mem_ptr, 4096, PROT_READ); | ||
| 3578 | // | ||
| 3579 | // code_page_set.push_back((uint64_t)mem_ptr); | ||
| 3580 | //#endif /* shenoubang */ | ||
| 3581 | //} | ||
| 3582 | |||
| 3583 | |||
| 3584 | |||
| 3585 | int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) | ||
| 3586 | { | ||
| 3587 | /* Decode instruction, get index */ | ||
| 3588 | /* Allocate memory and init InsCream */ | ||
| 3589 | /* Go on next, until terminal instruction */ | ||
| 3590 | /* Save start addr of basicblock in CreamCache */ | ||
| 3591 | //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); | ||
| 3592 | //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj); | ||
| 3593 | ARM_INST_PTR inst_base = NULL; | ||
| 3594 | unsigned int inst, inst_size = 4; | ||
| 3595 | int idx; | ||
| 3596 | int ret = NON_BRANCH; | ||
| 3597 | int thumb = 0; | ||
| 3598 | /* instruction size of basic block */ | ||
| 3599 | int size = 0; | ||
| 3600 | /* (R15 - 8) ? */ | ||
| 3601 | //cpu->translate_pc = cpu->Reg[15]; | ||
| 3602 | bb_start = top; | ||
| 3603 | |||
| 3604 | if (cpu->TFlag) | ||
| 3605 | thumb = THUMB; | ||
| 3606 | |||
| 3607 | addr_t phys_addr; | ||
| 3608 | addr_t pc_start; | ||
| 3609 | fault_t fault = NO_FAULT; | ||
| 3610 | //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB); | ||
| 3611 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 3612 | if(fault != NO_FAULT){ | ||
| 3613 | cpu->abortSig = true; | ||
| 3614 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3615 | cpu->AbortAddr = addr; | ||
| 3616 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3617 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 3618 | return FETCH_EXCEPTION; | ||
| 3619 | } | ||
| 3620 | pc_start = phys_addr; | ||
| 3621 | //phys_addr = get_dma_addr(phys_addr); | ||
| 3622 | while(ret == NON_BRANCH) { | ||
| 3623 | /* shenoubang add win32 2012-6-14 */ | ||
| 3624 | #ifdef __WIN32__ | ||
| 3625 | mem_bank_t* bank; | ||
| 3626 | if (bank = bank_ptr(addr)) { | ||
| 3627 | bank->bank_read(32, phys_addr, &inst); | ||
| 3628 | } | ||
| 3629 | else { | ||
| 3630 | DEBUG_LOG(ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr); | ||
| 3631 | return FETCH_FAILURE; | ||
| 3632 | } | ||
| 3633 | #else | ||
| 3634 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); | ||
| 3635 | #endif | ||
| 3636 | //or_tag(core, phys_addr, TAG_FAST_INTERP); | ||
| 3637 | |||
| 3638 | /*if (ret == FETCH_FAILURE) { | ||
| 3639 | return FETCH_EXCEPTION; | ||
| 3640 | }*/ | ||
| 3641 | |||
| 3642 | size ++; | ||
| 3643 | /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */ | ||
| 3644 | if (cpu->TFlag){ | ||
| 3645 | //if(cpu->Cpsr & (1 << THUMB_BIT)){ | ||
| 3646 | uint32_t arm_inst; | ||
| 3647 | tdstate state; | ||
| 3648 | state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); | ||
| 3649 | //or_tag(core, phys_addr, TAG_THUMB); | ||
| 3650 | //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); | ||
| 3651 | /* we have translated the branch instruction of thumb in thumb decoder */ | ||
| 3652 | if(state == t_branch){ | ||
| 3653 | goto translated; | ||
| 3654 | } | ||
| 3655 | inst = arm_inst; | ||
| 3656 | } | ||
| 3657 | |||
| 3658 | ret = decode_arm_instr(inst, &idx); | ||
| 3659 | if (ret == DECODE_FAILURE) { | ||
| 3660 | DEBUG_LOG(ARM11, "[info] : Decode failure.\tPC : [0x%x]\tInstruction : [%x]\n", phys_addr, inst); | ||
| 3661 | DEBUG_LOG(ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x\n", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | ||
| 3662 | CITRA_IGNORE_EXIT(-1); | ||
| 3663 | } | ||
| 3664 | // DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name); | ||
| 3665 | inst_base = arm_instruction_trans[idx](inst, idx); | ||
| 3666 | // DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst); | ||
| 3667 | // DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]); | ||
| 3668 | translated: | ||
| 3669 | phys_addr += inst_size; | ||
| 3670 | 3509 | ||
| 3671 | if ((phys_addr & 0xfff) == 0) { | 3510 | int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) { |
| 3672 | inst_base->br = END_OF_PAGE; | 3511 | // Decode instruction, get index |
| 3673 | } | 3512 | // Allocate memory and init InsCream |
| 3674 | ret = inst_base->br; | 3513 | // Go on next, until terminal instruction |
| 3675 | }; | 3514 | // Save start addr of basicblock in CreamCache |
| 3515 | ARM_INST_PTR inst_base = nullptr; | ||
| 3516 | unsigned int inst, inst_size = 4; | ||
| 3517 | int idx; | ||
| 3518 | int ret = NON_BRANCH; | ||
| 3519 | int thumb = 0; | ||
| 3520 | int size = 0; // instruction size of basic block | ||
| 3521 | bb_start = top; | ||
| 3522 | |||
| 3523 | if (cpu->TFlag) | ||
| 3524 | thumb = THUMB; | ||
| 3525 | |||
| 3526 | addr_t phys_addr; | ||
| 3527 | addr_t pc_start; | ||
| 3528 | fault_t fault = NO_FAULT; | ||
| 3529 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 3530 | if(fault != NO_FAULT){ | ||
| 3531 | cpu->abortSig = true; | ||
| 3532 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3533 | cpu->AbortAddr = addr; | ||
| 3534 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3535 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 3536 | return FETCH_EXCEPTION; | ||
| 3537 | } | ||
| 3676 | 3538 | ||
| 3677 | //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag); | 3539 | pc_start = phys_addr; |
| 3678 | insert_bb(pc_start, bb_start); | ||
| 3679 | return KEEP_GOING; | ||
| 3680 | } | ||
| 3681 | 3540 | ||
| 3682 | #define LOG_IN_CLR skyeye_printf_in_color | 3541 | while(ret == NON_BRANCH) { |
| 3542 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); | ||
| 3683 | 3543 | ||
| 3684 | int cmp(const void *x, const void *y) | 3544 | size ++; |
| 3685 | { | 3545 | // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction |
| 3686 | return *(unsigned long long int*)x - *(unsigned long long int *)y; | 3546 | if (cpu->TFlag) { |
| 3547 | uint32_t arm_inst; | ||
| 3548 | tdstate state; | ||
| 3549 | state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); | ||
| 3550 | // We have translated the branch instruction of thumb in thumb decoder | ||
| 3551 | if(state == t_branch){ | ||
| 3552 | goto translated; | ||
| 3553 | } | ||
| 3554 | inst = arm_inst; | ||
| 3555 | } | ||
| 3556 | |||
| 3557 | ret = decode_arm_instr(inst, &idx); | ||
| 3558 | if (ret == DECODE_FAILURE) { | ||
| 3559 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst); | ||
| 3560 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | ||
| 3561 | CITRA_IGNORE_EXIT(-1); | ||
| 3562 | } | ||
| 3563 | inst_base = arm_instruction_trans[idx](inst, idx); | ||
| 3564 | translated: | ||
| 3565 | phys_addr += inst_size; | ||
| 3566 | |||
| 3567 | if ((phys_addr & 0xfff) == 0) { | ||
| 3568 | inst_base->br = END_OF_PAGE; | ||
| 3569 | } | ||
| 3570 | ret = inst_base->br; | ||
| 3571 | }; | ||
| 3572 | insert_bb(pc_start, bb_start); | ||
| 3573 | return KEEP_GOING; | ||
| 3574 | } | ||
| 3575 | |||
| 3576 | #define LOG_IN_CLR skyeye_printf_in_color | ||
| 3577 | |||
| 3578 | int cmp(const void *x, const void *y) { | ||
| 3579 | return *(unsigned long long int*)x - *(unsigned long long int *)y; | ||
| 3580 | } | ||
| 3581 | |||
| 3582 | void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) { | ||
| 3583 | int array_size = size / sizeof(void *); | ||
| 3584 | unsigned long long int *InstLabel = new unsigned long long int[array_size]; | ||
| 3585 | memcpy(InstLabel, ptr, size); | ||
| 3586 | qsort(InstLabel, array_size, sizeof(void *), cmp); | ||
| 3587 | InstLength = new unsigned int[array_size - 4]; | ||
| 3588 | for (int i = 0; i < array_size - 4; i ++) { | ||
| 3589 | for (int j = 0; j < array_size; j ++) { | ||
| 3590 | if (ptr[i] == InstLabel[j]) { | ||
| 3591 | InstLength[i] = InstLabel[j + 1] - InstLabel[j]; | ||
| 3592 | break; | ||
| 3593 | } | ||
| 3594 | } | ||
| 3595 | } | ||
| 3596 | for (int i = 0; i < array_size - 4; i ++) | ||
| 3597 | LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]); | ||
| 3687 | } | 3598 | } |
| 3688 | 3599 | ||
| 3689 | void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) | 3600 | int clz(unsigned int x) { |
| 3690 | { | 3601 | int n; |
| 3691 | int array_size = size / sizeof(void *); | 3602 | if (x == 0) return (32); |
| 3692 | unsigned long long int *InstLabel = new unsigned long long int[array_size]; | 3603 | n = 1; |
| 3693 | memcpy(InstLabel, ptr, size); | 3604 | if ((x >> 16) == 0) { n = n + 16; x = x << 16;} |
| 3694 | qsort(InstLabel, array_size, sizeof(void *), cmp); | 3605 | if ((x >> 24) == 0) { n = n + 8; x = x << 8;} |
| 3695 | InstLength = new unsigned int[array_size - 4]; | 3606 | if ((x >> 28) == 0) { n = n + 4; x = x << 4;} |
| 3696 | for (int i = 0; i < array_size - 4; i ++) { | 3607 | if ((x >> 30) == 0) { n = n + 2; x = x << 2;} |
| 3697 | for (int j = 0; j < array_size; j ++) { | 3608 | n = n - (x >> 31); |
| 3698 | if (ptr[i] == InstLabel[j]) { | 3609 | return n; |
| 3699 | InstLength[i] = InstLabel[j + 1] - InstLabel[j]; | ||
| 3700 | break; | ||
| 3701 | } | ||
| 3702 | } | ||
| 3703 | } | ||
| 3704 | for (int i = 0; i < array_size - 4; i ++) | ||
| 3705 | DEBUG_LOG(ARM11, "[%d]:%d\n", i, InstLength[i]); | ||
| 3706 | } | ||
| 3707 | |||
| 3708 | int clz(unsigned int x) | ||
| 3709 | { | ||
| 3710 | int n; | ||
| 3711 | if (x == 0) return (32); | ||
| 3712 | n = 1; | ||
| 3713 | if ((x >> 16) == 0) { n = n + 16; x = x << 16;} | ||
| 3714 | if ((x >> 24) == 0) { n = n + 8; x = x << 8;} | ||
| 3715 | if ((x >> 28) == 0) { n = n + 4; x = x << 4;} | ||
| 3716 | if ((x >> 30) == 0) { n = n + 2; x = x << 2;} | ||
| 3717 | n = n - (x >> 31); | ||
| 3718 | return n; | ||
| 3719 | } | 3610 | } |
| 3720 | 3611 | ||
| 3721 | unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number); | 3612 | unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number); |
| 3722 | 3613 | ||
| 3723 | static bool InAPrivilegedMode(arm_core_t *core) | 3614 | static bool InAPrivilegedMode(arm_core_t *core) { |
| 3724 | { | 3615 | return (core->Mode != USER32MODE); |
| 3725 | return (core->Mode != USER32MODE); | ||
| 3726 | } | 3616 | } |
| 3727 | 3617 | ||
| 3728 | /* r15 = r15 + 8 */ | 3618 | unsigned InterpreterMainLoop(ARMul_State* state) { |
| 3729 | unsigned InterpreterMainLoop(ARMul_State* state) | 3619 | #define CRn inst_cream->crn |
| 3730 | { | 3620 | #define OPCODE_2 inst_cream->opcode_2 |
| 3731 | #define CRn inst_cream->crn | 3621 | #define CRm inst_cream->crm |
| 3732 | #define OPCODE_2 inst_cream->opcode_2 | 3622 | #define CP15_REG(n) cpu->CP15[CP15(n)] |
| 3733 | #define CRm inst_cream->crm | 3623 | #define RD cpu->Reg[inst_cream->Rd] |
| 3734 | #define CP15_REG(n) cpu->CP15[CP15(n)] | 3624 | #define RN cpu->Reg[inst_cream->Rn] |
| 3735 | #define RD cpu->Reg[inst_cream->Rd] | 3625 | #define RM cpu->Reg[inst_cream->Rm] |
| 3736 | #define RN cpu->Reg[inst_cream->Rn] | 3626 | #define RS cpu->Reg[inst_cream->Rs] |
| 3737 | #define RM cpu->Reg[inst_cream->Rm] | 3627 | #define RDHI cpu->Reg[inst_cream->RdHi] |
| 3738 | #define RS cpu->Reg[inst_cream->Rs] | 3628 | #define RDLO cpu->Reg[inst_cream->RdLo] |
| 3739 | #define RDHI cpu->Reg[inst_cream->RdHi] | 3629 | #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) |
| 3740 | #define RDLO cpu->Reg[inst_cream->RdLo] | 3630 | #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) |
| 3741 | #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) | 3631 | #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) |
| 3742 | #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) | 3632 | |
| 3743 | #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) | 3633 | #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \ |
| 3744 | 3634 | inst_base = (arm_inst *)&inst_buf[ptr] | |
| 3745 | #if ENABLE_ICOUNTER | 3635 | |
| 3746 | #define INC_ICOUNTER cpu->icounter++; \ | 3636 | #define INC_PC(l) ptr += sizeof(arm_inst) + l |
| 3747 | if(cpu->Reg[15] > 0xc0000000) \ | ||
| 3748 | cpu->kernel_icounter++; | ||
| 3749 | //if (debug_function(core)) \ | ||
| 3750 | if (core->check_int_flag) \ | ||
| 3751 | goto END | ||
| 3752 | //DEBUG_LOG(ARM11, "icounter is %llx line is %d pc is %x\n", cpu->icounter, __LINE__, cpu->Reg[15]) | ||
| 3753 | #else | ||
| 3754 | #define INC_ICOUNTER ; | ||
| 3755 | #endif | ||
| 3756 | |||
| 3757 | #define FETCH_INST if (inst_base->br != NON_BRANCH) \ | ||
| 3758 | goto DISPATCH; \ | ||
| 3759 | inst_base = (arm_inst *)&inst_buf[ptr] | ||
| 3760 | #define INC_PC(l) ptr += sizeof(arm_inst) + l | ||
| 3761 | 3637 | ||
| 3762 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a | 3638 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a |
| 3763 | // clunky switch statement. | 3639 | // clunky switch statement. |
| @@ -3898,7 +3774,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) | |||
| 3898 | case 124: goto PKHTB_INST; \ | 3774 | case 124: goto PKHTB_INST; \ |
| 3899 | case 125: goto PKHBT_INST; \ | 3775 | case 125: goto PKHBT_INST; \ |
| 3900 | case 126: goto SMUL_INST; \ | 3776 | case 126: goto SMUL_INST; \ |
| 3901 | case 127: goto SMLAL_INST; \ | 3777 | case 127: goto SMLALXY_INST; \ |
| 3902 | case 128: goto SMLA_INST; \ | 3778 | case 128: goto SMLA_INST; \ |
| 3903 | case 129: goto MCRR_INST; \ | 3779 | case 129: goto MCRR_INST; \ |
| 3904 | case 130: goto MRRC_INST; \ | 3780 | case 130: goto MRRC_INST; \ |
| @@ -3967,2606 +3843,2586 @@ unsigned InterpreterMainLoop(ARMul_State* state) | |||
| 3967 | } | 3843 | } |
| 3968 | #endif | 3844 | #endif |
| 3969 | 3845 | ||
| 3970 | #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) | 3846 | #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) |
| 3971 | #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) | 3847 | #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) |
| 3972 | // #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \ | 3848 | |
| 3973 | (ISNEG(lop) && ISPOS(dst)) || \ | 3849 | #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) |
| 3974 | (ISPOS(rop) && ISPOS(dst)))) | 3850 | #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) |
| 3975 | #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) | 3851 | #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) |
| 3976 | #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) | 3852 | #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) |
| 3977 | #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) | 3853 | #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) |
| 3978 | #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) | 3854 | #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) |
| 3979 | #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) | 3855 | |
| 3980 | #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out | 3856 | #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ |
| 3981 | // #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \ | 3857 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) |
| 3982 | (ISNEG(lop) && ISPOS(dst)) || \ | 3858 | #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ |
| 3983 | (ISPOS(rop) && ISPOS(dst))) | 3859 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) |
| 3984 | #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ | 3860 | #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) |
| 3985 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) | 3861 | |
| 3986 | #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ | 3862 | #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ |
| 3987 | ((lop >= 0) && (rop) >= 0 && (dst < 0)))) | 3863 | (cpu->NFlag << 31) | \ |
| 3988 | #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) | 3864 | (cpu->ZFlag << 30) | \ |
| 3989 | 3865 | (cpu->CFlag << 29) | \ | |
| 3990 | #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ | 3866 | (cpu->VFlag << 28) | \ |
| 3991 | (cpu->NFlag << 31) | \ | 3867 | (cpu->TFlag << 5) |
| 3992 | (cpu->ZFlag << 30) | \ | 3868 | #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ |
| 3993 | (cpu->CFlag << 29) | \ | 3869 | cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ |
| 3994 | (cpu->VFlag << 28) | \ | 3870 | cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ |
| 3995 | (cpu->TFlag << 5) | 3871 | cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ |
| 3996 | #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ | 3872 | cpu->TFlag = (cpu->Cpsr >> 5) & 1; |
| 3997 | cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ | 3873 | |
| 3998 | cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ | 3874 | #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) |
| 3999 | cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ | 3875 | #define PC (cpu->Reg[15]) |
| 4000 | cpu->TFlag = (cpu->Cpsr >> 5) & 1; | 3876 | #define CHECK_EXT_INT if (!cpu->NirqSig && !(cpu->Cpsr & 0x80)) goto END; |
| 4001 | 3877 | ||
| 4002 | #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) | 3878 | arm_processor *cpu = state; |
| 4003 | #define PC (cpu->Reg[15]) | ||
| 4004 | #define CHECK_EXT_INT if (!cpu->NirqSig) { \ | ||
| 4005 | if (!(cpu->Cpsr & 0x80)) { \ | ||
| 4006 | goto END; \ | ||
| 4007 | } \ | ||
| 4008 | } | ||
| 4009 | |||
| 4010 | |||
| 4011 | |||
| 4012 | //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t"); | ||
| 4013 | arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj); | ||
| 4014 | 3879 | ||
| 4015 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback | 3880 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback |
| 4016 | // to a clunky switch statement. | 3881 | // to a clunky switch statement. |
| 4017 | #if defined __GNUC__ || defined __clang__ | 3882 | #if defined __GNUC__ || defined __clang__ |
| 4018 | void *InstLabel[] = { | 3883 | void *InstLabel[] = { |
| 4019 | #define VFP_INTERPRETER_LABEL | 3884 | &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST, |
| 4020 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 3885 | &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST, |
| 4021 | #undef VFP_INTERPRETER_LABEL | 3886 | &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST, |
| 4022 | &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, | 3887 | &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST, |
| 4023 | &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, | 3888 | |
| 4024 | &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, | 3889 | &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, |
| 4025 | &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, | 3890 | &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, |
| 4026 | &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, | 3891 | &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, |
| 4027 | &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, | 3892 | &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, |
| 4028 | &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, | 3893 | &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, |
| 4029 | &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, | 3894 | &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, |
| 4030 | &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, | 3895 | &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, |
| 4031 | &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST, | 3896 | &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, |
| 4032 | &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, | 3897 | &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, |
| 4033 | &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, | 3898 | &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST, |
| 4034 | &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, | 3899 | &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, |
| 4035 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, | 3900 | &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, |
| 4036 | &&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, | 3901 | &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, |
| 4037 | &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END | 3902 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, |
| 4038 | }; | 3903 | &&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, |
| 4039 | #endif | 3904 | &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END |
| 4040 | arm_inst * inst_base; | 3905 | }; |
| 4041 | unsigned int lop, rop, dst; | ||
| 4042 | unsigned int addr; | ||
| 4043 | unsigned int phys_addr; | ||
| 4044 | unsigned int last_pc = 0; | ||
| 4045 | unsigned int num_instrs = 0; | ||
| 4046 | fault_t fault; | ||
| 4047 | static unsigned int last_physical_base = 0, last_logical_base = 0; | ||
| 4048 | int ptr; | ||
| 4049 | bool single_step = (cpu->NumInstrsToExecute == 1); | ||
| 4050 | |||
| 4051 | LOAD_NZCVT; | ||
| 4052 | DISPATCH: | ||
| 4053 | { | ||
| 4054 | if (!cpu->NirqSig) { | ||
| 4055 | if (!(cpu->Cpsr & 0x80)) { | ||
| 4056 | goto END; | ||
| 4057 | } | ||
| 4058 | } | ||
| 4059 | |||
| 4060 | if (cpu->TFlag) { | ||
| 4061 | cpu->Reg[15] &= 0xfffffffe; | ||
| 4062 | } else | ||
| 4063 | cpu->Reg[15] &= 0xfffffffc; | ||
| 4064 | #if PROFILE | ||
| 4065 | /* check next instruction address is valid. */ | ||
| 4066 | last_pc = cpu->Reg[15]; | ||
| 4067 | #endif | 3906 | #endif |
| 4068 | #if USER_MODE_OPT | 3907 | arm_inst * inst_base; |
| 4069 | phys_addr = cpu->Reg[15]; | 3908 | unsigned int lop, rop, dst; |
| 4070 | #else | 3909 | unsigned int addr; |
| 4071 | { | 3910 | unsigned int phys_addr; |
| 4072 | if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) | 3911 | unsigned int last_pc = 0; |
| 4073 | phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); | 3912 | unsigned int num_instrs = 0; |
| 4074 | else { | 3913 | fault_t fault; |
| 4075 | /* check next instruction address is valid. */ | 3914 | static unsigned int last_physical_base = 0, last_logical_base = 0; |
| 4076 | fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); | 3915 | int ptr; |
| 4077 | if (fault) { | 3916 | bool single_step = (cpu->NumInstrsToExecute == 1); |
| 4078 | cpu->abortSig = true; | 3917 | |
| 4079 | cpu->Aborted = ARMul_PrefetchAbortV; | 3918 | LOAD_NZCVT; |
| 4080 | cpu->AbortAddr = cpu->Reg[15]; | 3919 | DISPATCH: |
| 4081 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | 3920 | { |
| 4082 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; | 3921 | if (!cpu->NirqSig) { |
| 4083 | goto END; | 3922 | if (!(cpu->Cpsr & 0x80)) { |
| 4084 | } | 3923 | goto END; |
| 4085 | last_logical_base = cpu->Reg[15] & 0xfffff000; | 3924 | } |
| 4086 | last_physical_base = phys_addr & 0xfffff000; | 3925 | } |
| 4087 | } | 3926 | |
| 4088 | } | 3927 | if (cpu->TFlag) |
| 4089 | #if HYBRID_MODE | 3928 | cpu->Reg[15] &= 0xfffffffe; |
| 4090 | /* check if the native code of dyncom is available */ | 3929 | else |
| 4091 | //fast_map hash_map = core->dyncom_engine->fmap; | 3930 | cpu->Reg[15] &= 0xfffffffc; |
| 4092 | //void * pfunc = NULL; | 3931 | |
| 4093 | //PFUNC(phys_addr); | 3932 | phys_addr = cpu->Reg[15]; |
| 4094 | //if(pfunc){ | 3933 | |
| 4095 | if(is_translated_entry(core, phys_addr)){ | 3934 | if (find_bb(phys_addr, ptr) == -1) |
| 4096 | int rc = JIT_RETURN_NOERR; | ||
| 4097 | //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]); | ||
| 4098 | SAVE_NZCVT; | ||
| 4099 | // resume_timing(); | ||
| 4100 | rc = cpu_run(core); | ||
| 4101 | LOAD_NZCVT; | ||
| 4102 | //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]); | ||
| 4103 | if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){ | ||
| 4104 | /* keep the tflag same with the bit in CPSR */ | ||
| 4105 | //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT); | ||
| 4106 | //cpu->TFlag = cpu->Cpsr & (1 << 5); | ||
| 4107 | //switch_mode(cpu, cpu->Cpsr & 0x1f); | ||
| 4108 | //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]); | ||
| 4109 | fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); | ||
| 4110 | if (fault) { | ||
| 4111 | cpu->abortSig = true; | ||
| 4112 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 4113 | cpu->AbortAddr = cpu->Reg[15]; | ||
| 4114 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 4115 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; | ||
| 4116 | goto END; | ||
| 4117 | } | ||
| 4118 | last_logical_base = cpu->Reg[15] & 0xfffff000; | ||
| 4119 | last_physical_base = phys_addr & 0xfffff000; | ||
| 4120 | core->current_page_phys = last_physical_base; | ||
| 4121 | core->current_page_effec = last_logical_base; | ||
| 4122 | //push_to_compiled(core, phys_addr); | ||
| 4123 | } | ||
| 4124 | else{ | ||
| 4125 | if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){ | ||
| 4126 | //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]); | ||
| 4127 | //core->Reg[15] -= get_instr_size(cpu_dyncom); | ||
| 4128 | fill_tlb(cpu); | ||
| 4129 | goto END; | ||
| 4130 | } | ||
| 4131 | if (cpu->syscallSig) { | ||
| 4132 | goto END; | ||
| 4133 | } | ||
| 4134 | if (cpu->abortSig) { | ||
| 4135 | cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0; | ||
| 4136 | goto END; | ||
| 4137 | } | ||
| 4138 | if (!cpu->NirqSig) { | ||
| 4139 | if (!(cpu->Cpsr & 0x80)) { | ||
| 4140 | goto END; | ||
| 4141 | } | ||
| 4142 | } | ||
| 4143 | |||
| 4144 | /* if regular trap */ | ||
| 4145 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4146 | /*uint32_t mode = cpu->Cpsr & 0x1f; | ||
| 4147 | if ((mode != cpu->Mode) && (!is_user_mode(core))) { | ||
| 4148 | switch_mode(cpu, mode); | ||
| 4149 | return 1; | ||
| 4150 | }*/ | ||
| 4151 | |||
| 4152 | goto END; | ||
| 4153 | } | ||
| 4154 | //phys_addr = cpu->Reg[15]; | ||
| 4155 | } | ||
| 4156 | else{ | ||
| 4157 | if (last_logical_base == (cpu->Reg[15] & 0xfffff000)) | ||
| 4158 | phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff); | ||
| 4159 | else { | ||
| 4160 | /* check next instruction address is valid. */ | ||
| 4161 | fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB); | ||
| 4162 | if (fault) { | ||
| 4163 | cpu->abortSig = true; | ||
| 4164 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 4165 | cpu->AbortAddr = cpu->Reg[15]; | ||
| 4166 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 4167 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15]; | ||
| 4168 | goto END; | ||
| 4169 | } | ||
| 4170 | last_logical_base = cpu->Reg[15] & 0xfffff000; | ||
| 4171 | last_physical_base = phys_addr & 0xfffff000; | ||
| 4172 | } | ||
| 4173 | } | ||
| 4174 | #endif /* #if HYBRID_MODE */ | ||
| 4175 | #endif /* #if USER_MODE_OPT */ | ||
| 4176 | if (true){//if(is_fast_interp_code(core, phys_addr)){ | ||
| 4177 | if (find_bb(phys_addr, ptr) == -1) | ||
| 4178 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) | ||
| 4179 | goto END; | ||
| 4180 | } | ||
| 4181 | else{ | ||
| 4182 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) | 3935 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) |
| 4183 | goto END; | 3936 | goto END; |
| 4184 | } | 3937 | |
| 4185 | #if PROFILE | 3938 | inst_base = (arm_inst *)&inst_buf[ptr]; |
| 4186 | resume_timing(); | 3939 | GOTO_NEXT_INST; |
| 4187 | #endif | 3940 | } |
| 4188 | inst_base = (arm_inst *)&inst_buf[ptr]; | 3941 | ADC_INST: |
| 4189 | GOTO_NEXT_INST; | 3942 | { |
| 4190 | } | 3943 | adc_inst *inst_cream = (adc_inst *)inst_base->component; |
| 4191 | ADC_INST: | 3944 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4192 | { | 3945 | lop = RN; |
| 4193 | INC_ICOUNTER; | 3946 | unsigned int sht_op = SHIFTER_OPERAND; |
| 4194 | adc_inst *inst_cream = (adc_inst *)inst_base->component; | 3947 | rop = SHIFTER_OPERAND + cpu->CFlag; |
| 4195 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3948 | RD = dst = lop + rop; |
| 4196 | lop = RN; | 3949 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4197 | unsigned int sht_op = SHIFTER_OPERAND; | 3950 | if (CurrentModeHasSPSR) { |
| 4198 | rop = SHIFTER_OPERAND + cpu->CFlag; | 3951 | cpu->Cpsr = cpu->Spsr_copy; |
| 4199 | RD = dst = lop + rop; | 3952 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 4200 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3953 | LOAD_NZCVT; |
| 4201 | /* cpsr = spsr */ | 3954 | } |
| 4202 | if (CurrentModeHasSPSR) { | 3955 | } else if (inst_cream->S) { |
| 4203 | cpu->Cpsr = cpu->Spsr_copy; | 3956 | UPDATE_NFLAG(dst); |
| 4204 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 3957 | UPDATE_ZFLAG(dst); |
| 4205 | LOAD_NZCVT; | 3958 | UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); |
| 4206 | } | 3959 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); |
| 4207 | } else if (inst_cream->S) { | 3960 | } |
| 4208 | UPDATE_NFLAG(dst); | 3961 | if (inst_cream->Rd == 15) { |
| 4209 | UPDATE_ZFLAG(dst); | 3962 | INC_PC(sizeof(adc_inst)); |
| 4210 | UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); | 3963 | goto DISPATCH; |
| 4211 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 3964 | } |
| 4212 | } | 3965 | } |
| 4213 | if (inst_cream->Rd == 15) { | 3966 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4214 | INC_PC(sizeof(adc_inst)); | 3967 | INC_PC(sizeof(adc_inst)); |
| 4215 | goto DISPATCH; | 3968 | FETCH_INST; |
| 4216 | } | 3969 | GOTO_NEXT_INST; |
| 4217 | } | 3970 | } |
| 4218 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3971 | ADD_INST: |
| 4219 | INC_PC(sizeof(adc_inst)); | 3972 | { |
| 4220 | FETCH_INST; | 3973 | add_inst *inst_cream = (add_inst *)inst_base->component; |
| 4221 | GOTO_NEXT_INST; | 3974 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4222 | } | 3975 | lop = RN; |
| 4223 | ADD_INST: | 3976 | if (inst_cream->Rn == 15) { |
| 4224 | { | 3977 | lop += 2 * GET_INST_SIZE(cpu); |
| 4225 | INC_ICOUNTER; | 3978 | } |
| 4226 | add_inst *inst_cream = (add_inst *)inst_base->component; | 3979 | rop = SHIFTER_OPERAND; |
| 4227 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3980 | RD = dst = lop + rop; |
| 4228 | lop = RN; | 3981 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4229 | if (inst_cream->Rn == 15) { | 3982 | if (CurrentModeHasSPSR) { |
| 4230 | lop += 2 * GET_INST_SIZE(cpu); | 3983 | cpu->Cpsr = cpu->Spsr_copy; |
| 4231 | } | 3984 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4232 | rop = SHIFTER_OPERAND; | 3985 | LOAD_NZCVT; |
| 4233 | RD = dst = lop + rop; | 3986 | } |
| 4234 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3987 | } else if (inst_cream->S) { |
| 4235 | /* cpsr = spsr*/ | 3988 | UPDATE_NFLAG(dst); |
| 4236 | if (CurrentModeHasSPSR) { | 3989 | UPDATE_ZFLAG(dst); |
| 4237 | cpu->Cpsr = cpu->Spsr_copy; | 3990 | UPDATE_CFLAG(dst, lop, rop); |
| 4238 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 3991 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); |
| 4239 | LOAD_NZCVT; | 3992 | } |
| 4240 | } | 3993 | if (inst_cream->Rd == 15) { |
| 4241 | } else if (inst_cream->S) { | 3994 | INC_PC(sizeof(add_inst)); |
| 4242 | UPDATE_NFLAG(dst); | 3995 | goto DISPATCH; |
| 4243 | UPDATE_ZFLAG(dst); | 3996 | } |
| 4244 | UPDATE_CFLAG(dst, lop, rop); | 3997 | } |
| 4245 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 3998 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4246 | } | 3999 | INC_PC(sizeof(add_inst)); |
| 4247 | if (inst_cream->Rd == 15) { | 4000 | FETCH_INST; |
| 4248 | INC_PC(sizeof(add_inst)); | 4001 | GOTO_NEXT_INST; |
| 4249 | goto DISPATCH; | 4002 | } |
| 4250 | } | 4003 | AND_INST: |
| 4251 | } | 4004 | { |
| 4252 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4005 | and_inst *inst_cream = (and_inst *)inst_base->component; |
| 4253 | INC_PC(sizeof(add_inst)); | 4006 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4254 | FETCH_INST; | 4007 | lop = RN; |
| 4255 | GOTO_NEXT_INST; | 4008 | rop = SHIFTER_OPERAND; |
| 4256 | } | 4009 | RD = dst = lop & rop; |
| 4257 | AND_INST: | 4010 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4258 | { | 4011 | if (CurrentModeHasSPSR) { |
| 4259 | INC_ICOUNTER; | 4012 | cpu->Cpsr = cpu->Spsr_copy; |
| 4260 | and_inst *inst_cream = (and_inst *)inst_base->component; | 4013 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4261 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4014 | LOAD_NZCVT; |
| 4262 | lop = RN; | 4015 | } |
| 4263 | rop = SHIFTER_OPERAND; | 4016 | } else if (inst_cream->S) { |
| 4264 | RD = dst = lop & rop; | 4017 | UPDATE_NFLAG(dst); |
| 4265 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4018 | UPDATE_ZFLAG(dst); |
| 4266 | /* cpsr = spsr*/ | 4019 | UPDATE_CFLAG_WITH_SC; |
| 4267 | if (CurrentModeHasSPSR) { | 4020 | } |
| 4268 | cpu->Cpsr = cpu->Spsr_copy; | 4021 | if (inst_cream->Rd == 15) { |
| 4269 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4022 | INC_PC(sizeof(and_inst)); |
| 4270 | LOAD_NZCVT; | 4023 | goto DISPATCH; |
| 4271 | } | 4024 | } |
| 4272 | } else if (inst_cream->S) { | 4025 | } |
| 4273 | UPDATE_NFLAG(dst); | 4026 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4274 | UPDATE_ZFLAG(dst); | 4027 | INC_PC(sizeof(and_inst)); |
| 4275 | UPDATE_CFLAG_WITH_SC; | 4028 | FETCH_INST; |
| 4276 | //UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4029 | GOTO_NEXT_INST; |
| 4277 | } | 4030 | } |
| 4278 | if (inst_cream->Rd == 15) { | 4031 | BBL_INST: |
| 4279 | INC_PC(sizeof(and_inst)); | 4032 | { |
| 4280 | goto DISPATCH; | 4033 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4281 | } | 4034 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; |
| 4282 | } | 4035 | if (inst_cream->L) { |
| 4283 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4036 | LINK_RTN_ADDR; |
| 4284 | INC_PC(sizeof(and_inst)); | 4037 | } |
| 4285 | FETCH_INST; | 4038 | SET_PC; |
| 4286 | GOTO_NEXT_INST; | 4039 | INC_PC(sizeof(bbl_inst)); |
| 4287 | } | 4040 | goto DISPATCH; |
| 4288 | BBL_INST: | 4041 | } |
| 4289 | { | 4042 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4290 | INC_ICOUNTER; | 4043 | INC_PC(sizeof(bbl_inst)); |
| 4291 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4044 | goto DISPATCH; |
| 4292 | bbl_inst *inst_cream = (bbl_inst *)inst_base->component; | 4045 | } |
| 4293 | if (inst_cream->L) { | 4046 | BIC_INST: |
| 4294 | LINK_RTN_ADDR; | 4047 | { |
| 4295 | } | 4048 | bic_inst *inst_cream = (bic_inst *)inst_base->component; |
| 4296 | SET_PC; | 4049 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4297 | INC_PC(sizeof(bbl_inst)); | 4050 | lop = RN; |
| 4298 | goto DISPATCH; | 4051 | if (inst_cream->Rn == 15) { |
| 4299 | } | 4052 | lop += 2 * GET_INST_SIZE(cpu); |
| 4300 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4053 | } |
| 4301 | INC_PC(sizeof(bbl_inst)); | 4054 | rop = SHIFTER_OPERAND; |
| 4302 | goto DISPATCH; | 4055 | RD = dst = lop & (~rop); |
| 4303 | } | 4056 | if ((inst_cream->S) && (inst_cream->Rd == 15)) { |
| 4304 | BIC_INST: | 4057 | if (CurrentModeHasSPSR) { |
| 4305 | { | 4058 | cpu->Cpsr = cpu->Spsr_copy; |
| 4306 | INC_ICOUNTER; | 4059 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 4307 | bic_inst *inst_cream = (bic_inst *)inst_base->component; | 4060 | LOAD_NZCVT; |
| 4308 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4061 | } |
| 4309 | lop = RN; | 4062 | } else if (inst_cream->S) { |
| 4310 | if (inst_cream->Rn == 15) { | 4063 | UPDATE_NFLAG(dst); |
| 4311 | lop += 2 * GET_INST_SIZE(cpu); | 4064 | UPDATE_ZFLAG(dst); |
| 4312 | } | 4065 | UPDATE_CFLAG_WITH_SC; |
| 4313 | rop = SHIFTER_OPERAND; | 4066 | } |
| 4314 | // RD = dst = lop & (rop ^ 0xffffffff); | 4067 | if (inst_cream->Rd == 15) { |
| 4315 | RD = dst = lop & (~rop); | 4068 | INC_PC(sizeof(bic_inst)); |
| 4316 | if ((inst_cream->S) && (inst_cream->Rd == 15)) { | 4069 | goto DISPATCH; |
| 4317 | /* cpsr = spsr */ | 4070 | } |
| 4318 | if (CurrentModeHasSPSR) { | 4071 | } |
| 4319 | cpu->Cpsr = cpu->Spsr_copy; | 4072 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4320 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4073 | INC_PC(sizeof(bic_inst)); |
| 4321 | LOAD_NZCVT; | 4074 | FETCH_INST; |
| 4322 | } | 4075 | GOTO_NEXT_INST; |
| 4323 | } else if (inst_cream->S) { | 4076 | } |
| 4324 | UPDATE_NFLAG(dst); | 4077 | BKPT_INST: |
| 4325 | UPDATE_ZFLAG(dst); | 4078 | BLX_INST: |
| 4326 | UPDATE_CFLAG_WITH_SC; | 4079 | { |
| 4327 | } | 4080 | blx_inst *inst_cream = (blx_inst *)inst_base->component; |
| 4328 | if (inst_cream->Rd == 15) { | 4081 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4329 | INC_PC(sizeof(bic_inst)); | 4082 | unsigned int inst = inst_cream->inst; |
| 4330 | goto DISPATCH; | 4083 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { |
| 4331 | } | 4084 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); |
| 4332 | } | 4085 | if(cpu->TFlag) |
| 4333 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4086 | cpu->Reg[14] |= 0x1; |
| 4334 | INC_PC(sizeof(bic_inst)); | 4087 | cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; |
| 4335 | FETCH_INST; | 4088 | cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; |
| 4336 | GOTO_NEXT_INST; | 4089 | } else { |
| 4337 | } | 4090 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); |
| 4338 | BKPT_INST: | 4091 | cpu->TFlag = 0x1; |
| 4339 | BLX_INST: | 4092 | int signed_int = inst_cream->val.signed_immed_24; |
| 4340 | { | 4093 | signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; |
| 4341 | INC_ICOUNTER; | 4094 | signed_int = signed_int << 2; |
| 4342 | blx_inst *inst_cream = (blx_inst *)inst_base->component; | 4095 | cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1); |
| 4343 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4096 | } |
| 4344 | unsigned int inst = inst_cream->inst; | 4097 | INC_PC(sizeof(blx_inst)); |
| 4345 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { | 4098 | goto DISPATCH; |
| 4346 | //LINK_RTN_ADDR; | 4099 | } |
| 4347 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); | 4100 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4348 | if(cpu->TFlag) | 4101 | INC_PC(sizeof(blx_inst)); |
| 4349 | cpu->Reg[14] |= 0x1; | 4102 | goto DISPATCH; |
| 4350 | cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; | 4103 | } |
| 4351 | cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; | 4104 | BX_INST: |
| 4352 | //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe; | 4105 | { |
| 4353 | //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1; | 4106 | bx_inst *inst_cream = (bx_inst *)inst_base->component; |
| 4354 | } else { | 4107 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4355 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); | 4108 | if (inst_cream->Rm == 15) |
| 4356 | cpu->TFlag = 0x1; | 4109 | LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); |
| 4357 | int signed_int = inst_cream->val.signed_immed_24; | 4110 | cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; |
| 4358 | signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; | 4111 | cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; |
| 4359 | signed_int = signed_int << 2; | 4112 | INC_PC(sizeof(bx_inst)); |
| 4360 | // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu) | 4113 | goto DISPATCH; |
| 4361 | cpu->Reg[15] = cpu->Reg[15] + 8 | 4114 | } |
| 4362 | + signed_int + (BIT(inst, 24) << 1); | 4115 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4363 | //DEBUG_MSG; | 4116 | INC_PC(sizeof(bx_inst)); |
| 4364 | } | 4117 | goto DISPATCH; |
| 4365 | INC_PC(sizeof(blx_inst)); | 4118 | } |
| 4366 | goto DISPATCH; | 4119 | BXJ_INST: |
| 4367 | } | 4120 | CDP_INST: |
| 4368 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4121 | { |
| 4369 | // INC_PC(sizeof(bx_inst)); | 4122 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; |
| 4370 | INC_PC(sizeof(blx_inst)); | 4123 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4371 | goto DISPATCH; | 4124 | // Undefined instruction here |
| 4372 | } | 4125 | cpu->NumInstrsToExecute = 0; |
| 4373 | BX_INST: | 4126 | return num_instrs; |
| 4374 | { | 4127 | } |
| 4375 | INC_ICOUNTER; | 4128 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4376 | bx_inst *inst_cream = (bx_inst *)inst_base->component; | 4129 | INC_PC(sizeof(cdp_inst)); |
| 4377 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4130 | FETCH_INST; |
| 4378 | if (inst_cream->Rm == 15) | 4131 | GOTO_NEXT_INST; |
| 4379 | DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]); | 4132 | } |
| 4380 | cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; | 4133 | |
| 4381 | cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe; | 4134 | CLREX_INST: |
| 4382 | // cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1; | 4135 | { |
| 4383 | INC_PC(sizeof(bx_inst)); | 4136 | remove_exclusive(cpu, 0); |
| 4384 | goto DISPATCH; | 4137 | cpu->exclusive_state = 0; |
| 4385 | } | 4138 | |
| 4386 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4139 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4387 | // INC_PC(sizeof(bx_inst)); | 4140 | INC_PC(sizeof(clrex_inst)); |
| 4388 | INC_PC(sizeof(bx_inst)); | 4141 | FETCH_INST; |
| 4389 | goto DISPATCH; | 4142 | GOTO_NEXT_INST; |
| 4390 | } | 4143 | } |
| 4391 | BXJ_INST: | 4144 | CLZ_INST: |
| 4392 | CDP_INST: | 4145 | { |
| 4393 | { | 4146 | clz_inst *inst_cream = (clz_inst *)inst_base->component; |
| 4394 | INC_ICOUNTER; | 4147 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4395 | cdp_inst *inst_cream = (cdp_inst *)inst_base->component; | 4148 | RD = clz(RM); |
| 4396 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4149 | } |
| 4397 | /* FIXME, check if cp access allowed */ | 4150 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4398 | #define CP_ACCESS_ALLOW 0 | 4151 | INC_PC(sizeof(clz_inst)); |
| 4399 | if(CP_ACCESS_ALLOW){ | 4152 | FETCH_INST; |
| 4400 | /* undefined instruction here */ | 4153 | GOTO_NEXT_INST; |
| 4401 | cpu->NumInstrsToExecute = 0; | 4154 | } |
| 4402 | return num_instrs; | 4155 | CMN_INST: |
| 4403 | } | 4156 | { |
| 4404 | ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); | 4157 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; |
| 4405 | unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); | 4158 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4406 | if(cpab != ARMul_DONE){ | 4159 | lop = RN; |
| 4407 | ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num); | 4160 | rop = SHIFTER_OPERAND; |
| 4408 | //CITRA_IGNORE_EXIT(-1); | 4161 | dst = lop + rop; |
| 4409 | } | 4162 | UPDATE_NFLAG(dst); |
| 4410 | } | 4163 | UPDATE_ZFLAG(dst); |
| 4411 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4164 | UPDATE_CFLAG(dst, lop, rop); |
| 4412 | INC_PC(sizeof(cdp_inst)); | 4165 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); |
| 4413 | FETCH_INST; | 4166 | } |
| 4414 | GOTO_NEXT_INST; | 4167 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4415 | } | 4168 | INC_PC(sizeof(cmn_inst)); |
| 4416 | 4169 | FETCH_INST; | |
| 4417 | CLREX_INST: | 4170 | GOTO_NEXT_INST; |
| 4418 | { | 4171 | } |
| 4419 | INC_ICOUNTER; | 4172 | CMP_INST: |
| 4420 | remove_exclusive(cpu, 0); | 4173 | { |
| 4421 | cpu->exclusive_state = 0; | 4174 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4422 | 4175 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | |
| 4423 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4176 | lop = RN; |
| 4424 | INC_PC(sizeof(clrex_inst)); | 4177 | if (inst_cream->Rn == 15) { |
| 4425 | FETCH_INST; | 4178 | lop += 2 * GET_INST_SIZE(cpu); |
| 4426 | GOTO_NEXT_INST; | 4179 | } |
| 4427 | } | 4180 | rop = SHIFTER_OPERAND; |
| 4428 | CLZ_INST: | 4181 | dst = lop - rop; |
| 4429 | { | 4182 | |
| 4430 | INC_ICOUNTER; | 4183 | UPDATE_NFLAG(dst); |
| 4431 | clz_inst *inst_cream = (clz_inst *)inst_base->component; | 4184 | UPDATE_ZFLAG(dst); |
| 4432 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4185 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); |
| 4433 | RD = clz(RM); | 4186 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); |
| 4434 | } | 4187 | } |
| 4435 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4188 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4436 | INC_PC(sizeof(clz_inst)); | 4189 | INC_PC(sizeof(cmp_inst)); |
| 4437 | FETCH_INST; | 4190 | FETCH_INST; |
| 4438 | GOTO_NEXT_INST; | 4191 | GOTO_NEXT_INST; |
| 4439 | } | 4192 | } |
| 4440 | CMN_INST: | 4193 | CPS_INST: |
| 4441 | { | 4194 | { |
| 4442 | INC_ICOUNTER; | 4195 | cps_inst *inst_cream = (cps_inst *)inst_base->component; |
| 4443 | cmn_inst *inst_cream = (cmn_inst *)inst_base->component; | 4196 | uint32_t aif_val = 0; |
| 4444 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4197 | uint32_t aif_mask = 0; |
| 4445 | // DEBUG_LOG(ARM11, "RN is %x\n", RN); | 4198 | if (InAPrivilegedMode(cpu)) { |
| 4446 | lop = RN; | 4199 | if (inst_cream->imod1) { |
| 4447 | rop = SHIFTER_OPERAND; | 4200 | if (inst_cream->A) { |
| 4448 | dst = lop + rop; | 4201 | aif_val |= (inst_cream->imod0 << 8); |
| 4449 | UPDATE_NFLAG(dst); | 4202 | aif_mask |= 1 << 8; |
| 4450 | UPDATE_ZFLAG(dst); | 4203 | } |
| 4451 | UPDATE_CFLAG(dst, lop, rop); | 4204 | if (inst_cream->I) { |
| 4452 | UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4205 | aif_val |= (inst_cream->imod0 << 7); |
| 4453 | } | 4206 | aif_mask |= 1 << 7; |
| 4454 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4207 | } |
| 4455 | INC_PC(sizeof(cmn_inst)); | 4208 | if (inst_cream->F) { |
| 4456 | FETCH_INST; | 4209 | aif_val |= (inst_cream->imod0 << 6); |
| 4457 | GOTO_NEXT_INST; | 4210 | aif_mask |= 1 << 6; |
| 4458 | } | 4211 | } |
| 4459 | CMP_INST: | 4212 | aif_mask = ~aif_mask; |
| 4460 | { | 4213 | cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; |
| 4461 | // DEBUG_LOG(ARM11, "cmp inst\n"); | 4214 | } |
| 4462 | // DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); | 4215 | if (inst_cream->mmod) { |
| 4463 | INC_ICOUNTER; | 4216 | cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; |
| 4464 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4217 | switch_mode(cpu, inst_cream->mode); |
| 4465 | // DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]); | 4218 | } |
| 4466 | cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | 4219 | } |
| 4467 | lop = RN; | 4220 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4468 | if (inst_cream->Rn == 15) { | 4221 | INC_PC(sizeof(cps_inst)); |
| 4469 | lop += 2 * GET_INST_SIZE(cpu); | 4222 | FETCH_INST; |
| 4470 | } | 4223 | GOTO_NEXT_INST; |
| 4471 | rop = SHIFTER_OPERAND; | 4224 | } |
| 4472 | dst = lop - rop; | 4225 | CPY_INST: |
| 4473 | 4226 | { | |
| 4474 | UPDATE_NFLAG(dst); | 4227 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 4475 | UPDATE_ZFLAG(dst); | 4228 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4476 | // UPDATE_CFLAG(dst, lop, rop); | 4229 | RD = SHIFTER_OPERAND; |
| 4477 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | 4230 | if ((inst_cream->Rd == 15)) { |
| 4478 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4231 | INC_PC(sizeof(mov_inst)); |
| 4479 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | 4232 | goto DISPATCH; |
| 4480 | // UPDATE_VFLAG_WITH_NOT(dst, lop, rop); | 4233 | } |
| 4481 | } | 4234 | } |
| 4482 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4235 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4483 | INC_PC(sizeof(cmp_inst)); | 4236 | INC_PC(sizeof(mov_inst)); |
| 4484 | FETCH_INST; | 4237 | FETCH_INST; |
| 4485 | GOTO_NEXT_INST; | 4238 | GOTO_NEXT_INST; |
| 4486 | } | 4239 | } |
| 4487 | CPS_INST: | 4240 | EOR_INST: |
| 4488 | { | 4241 | { |
| 4489 | INC_ICOUNTER; | 4242 | eor_inst *inst_cream = (eor_inst *)inst_base->component; |
| 4490 | cps_inst *inst_cream = (cps_inst *)inst_base->component; | 4243 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4491 | uint32_t aif_val = 0; | 4244 | lop = RN; |
| 4492 | uint32_t aif_mask = 0; | 4245 | if (inst_cream->Rn == 15) { |
| 4493 | if (InAPrivilegedMode(cpu)) { | 4246 | lop += 2 * GET_INST_SIZE(cpu); |
| 4494 | /* isInAPrivilegedMode */ | 4247 | } |
| 4495 | if (inst_cream->imod1) { | 4248 | rop = SHIFTER_OPERAND; |
| 4496 | if (inst_cream->A) { | 4249 | RD = dst = lop ^ rop; |
| 4497 | aif_val |= (inst_cream->imod0 << 8); | 4250 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4498 | aif_mask |= 1 << 8; | 4251 | if (CurrentModeHasSPSR) { |
| 4499 | } | 4252 | cpu->Cpsr = cpu->Spsr_copy; |
| 4500 | if (inst_cream->I) { | 4253 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 4501 | aif_val |= (inst_cream->imod0 << 7); | 4254 | LOAD_NZCVT; |
| 4502 | aif_mask |= 1 << 7; | 4255 | } |
| 4503 | } | 4256 | } else if (inst_cream->S) { |
| 4504 | if (inst_cream->F) { | 4257 | UPDATE_NFLAG(dst); |
| 4505 | aif_val |= (inst_cream->imod0 << 6); | 4258 | UPDATE_ZFLAG(dst); |
| 4506 | aif_mask |= 1 << 6; | 4259 | UPDATE_CFLAG_WITH_SC; |
| 4507 | } | 4260 | } |
| 4508 | aif_mask = ~aif_mask; | 4261 | if (inst_cream->Rd == 15) { |
| 4509 | cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; | 4262 | INC_PC(sizeof(eor_inst)); |
| 4510 | } | 4263 | goto DISPATCH; |
| 4511 | if (inst_cream->mmod) { | 4264 | } |
| 4512 | cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; | 4265 | } |
| 4513 | switch_mode(cpu, inst_cream->mode); | 4266 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4514 | } | 4267 | INC_PC(sizeof(eor_inst)); |
| 4515 | } | 4268 | FETCH_INST; |
| 4516 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4269 | GOTO_NEXT_INST; |
| 4517 | INC_PC(sizeof(cps_inst)); | 4270 | } |
| 4518 | FETCH_INST; | 4271 | LDC_INST: |
| 4519 | GOTO_NEXT_INST; | 4272 | { |
| 4520 | } | 4273 | // Instruction not implemented |
| 4521 | CPY_INST: | 4274 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 4522 | { | 4275 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4523 | INC_ICOUNTER; | 4276 | INC_PC(sizeof(ldc_inst)); |
| 4524 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 4277 | FETCH_INST; |
| 4525 | // cpy_inst *inst_cream = (cpy_inst *)inst_base->component; | 4278 | GOTO_NEXT_INST; |
| 4526 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4279 | } |
| 4527 | RD = SHIFTER_OPERAND; | 4280 | LDM_INST: |
| 4528 | // RD = RM; | 4281 | { |
| 4529 | if ((inst_cream->Rd == 15)) { | 4282 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4530 | INC_PC(sizeof(mov_inst)); | 4283 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4531 | goto DISPATCH; | 4284 | int i; |
| 4532 | } | 4285 | unsigned int ret; |
| 4533 | } | 4286 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4534 | // DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]); | 4287 | if (fault) { |
| 4535 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4288 | goto MMU_EXCEPTION; |
| 4536 | INC_PC(sizeof(mov_inst)); | 4289 | } |
| 4537 | FETCH_INST; | 4290 | unsigned int inst = inst_cream->inst; |
| 4538 | GOTO_NEXT_INST; | 4291 | if (BIT(inst, 22) && !BIT(inst, 15)) { |
| 4539 | } | 4292 | for (i = 0; i < 13; i++) { |
| 4540 | EOR_INST: | 4293 | if(BIT(inst, i)){ |
| 4541 | { | 4294 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4542 | INC_ICOUNTER; | 4295 | cpu->Reg[i] = ret; |
| 4543 | eor_inst *inst_cream = (eor_inst *)inst_base->component; | 4296 | addr += 4; |
| 4544 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4297 | if ((addr & 0xfff) == 0) { |
| 4545 | lop = RN; | 4298 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4546 | if (inst_cream->Rn == 15) { | 4299 | } else { |
| 4547 | lop += 2 * GET_INST_SIZE(cpu); | 4300 | phys_addr += 4; |
| 4548 | } | 4301 | } |
| 4549 | rop = SHIFTER_OPERAND; | 4302 | } |
| 4550 | RD = dst = lop ^ rop; | 4303 | } |
| 4551 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4304 | if (BIT(inst, 13)) { |
| 4552 | /* cpsr = spsr*/ | 4305 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4553 | if (CurrentModeHasSPSR) { | 4306 | |
| 4554 | cpu->Cpsr = cpu->Spsr_copy; | 4307 | if (cpu->Mode == USER32MODE) |
| 4555 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4308 | cpu->Reg[13] = ret; |
| 4556 | LOAD_NZCVT; | 4309 | else |
| 4557 | } | 4310 | cpu->Reg_usr[0] = ret; |
| 4558 | } else if (inst_cream->S) { | 4311 | addr += 4; |
| 4559 | UPDATE_NFLAG(dst); | 4312 | if ((addr & 0xfff) == 0) { |
| 4560 | UPDATE_ZFLAG(dst); | 4313 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4561 | UPDATE_CFLAG_WITH_SC; | 4314 | } else { |
| 4562 | // UPDATE_CFLAG(dst, lop, rop); | 4315 | phys_addr += 4; |
| 4563 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 4316 | } |
| 4564 | } | 4317 | } |
| 4565 | if (inst_cream->Rd == 15) { | 4318 | if (BIT(inst, 14)) { |
| 4566 | INC_PC(sizeof(eor_inst)); | 4319 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4567 | goto DISPATCH; | 4320 | |
| 4568 | } | 4321 | if (cpu->Mode == USER32MODE) |
| 4569 | } | 4322 | cpu->Reg[14] = ret; |
| 4570 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4323 | else |
| 4571 | INC_PC(sizeof(eor_inst)); | 4324 | cpu->Reg_usr[1] = ret; |
| 4572 | FETCH_INST; | 4325 | } |
| 4573 | GOTO_NEXT_INST; | 4326 | } else if (!BIT(inst, 22)) { |
| 4574 | } | 4327 | for( i = 0; i < 16; i ++ ){ |
| 4575 | LDC_INST: | 4328 | if(BIT(inst, i)){ |
| 4576 | { | 4329 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4577 | INC_ICOUNTER; | 4330 | if (fault) goto MMU_EXCEPTION; |
| 4578 | /* NOT IMPL */ | 4331 | |
| 4579 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4332 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4580 | INC_PC(sizeof(ldc_inst)); | 4333 | if(i == 15){ |
| 4581 | FETCH_INST; | 4334 | cpu->TFlag = ret & 0x1; |
| 4582 | GOTO_NEXT_INST; | 4335 | ret &= 0xFFFFFFFE; |
| 4583 | } | ||
| 4584 | LDM_INST: | ||
| 4585 | { | ||
| 4586 | INC_ICOUNTER; | ||
| 4587 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4588 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4589 | int i; | ||
| 4590 | unsigned int ret; | ||
| 4591 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4592 | if (fault) { | ||
| 4593 | goto MMU_EXCEPTION; | ||
| 4594 | } | ||
| 4595 | unsigned int inst = inst_cream->inst; | ||
| 4596 | if (BIT(inst, 22) && !BIT(inst, 15)) { | ||
| 4597 | // DEBUG_MSG; | ||
| 4598 | #if 1 | ||
| 4599 | /* LDM (2) user */ | ||
| 4600 | for (i = 0; i < 13; i++) { | ||
| 4601 | if(BIT(inst, i)){ | ||
| 4602 | #if 0 | ||
| 4603 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4604 | if (fault) { | ||
| 4605 | goto MMU_EXCEPTION; | ||
| 4606 | } | ||
| 4607 | #endif | ||
| 4608 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4609 | //if (fault) goto MMU_EXCEPTION; | ||
| 4610 | cpu->Reg[i] = ret; | ||
| 4611 | addr += 4; | ||
| 4612 | if ((addr & 0xfff) == 0) { | ||
| 4613 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4614 | } else { | ||
| 4615 | phys_addr += 4; | ||
| 4616 | } | ||
| 4617 | } | ||
| 4618 | } | ||
| 4619 | if (BIT(inst, 13)) { | ||
| 4620 | #if 0 | ||
| 4621 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4622 | if (fault) { | ||
| 4623 | goto MMU_EXCEPTION; | ||
| 4624 | } | ||
| 4625 | #endif | ||
| 4626 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4627 | //if (fault) goto MMU_EXCEPTION; | ||
| 4628 | if (cpu->Mode == USER32MODE) | ||
| 4629 | cpu->Reg[13] = ret; | ||
| 4630 | else | ||
| 4631 | cpu->Reg_usr[0] = ret; | ||
| 4632 | addr += 4; | ||
| 4633 | if ((addr & 0xfff) == 0) { | ||
| 4634 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4635 | } else { | ||
| 4636 | phys_addr += 4; | ||
| 4637 | } | ||
| 4638 | } | ||
| 4639 | if (BIT(inst, 14)) { | ||
| 4640 | #if 0 | ||
| 4641 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4642 | if (fault) { | ||
| 4643 | goto MMU_EXCEPTION; | ||
| 4644 | } | ||
| 4645 | #endif | ||
| 4646 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4647 | //if (fault) goto MMU_EXCEPTION; | ||
| 4648 | if (cpu->Mode == USER32MODE) | ||
| 4649 | cpu->Reg[14] = ret; | ||
| 4650 | else | ||
| 4651 | cpu->Reg_usr[1] = ret; | ||
| 4652 | } | ||
| 4653 | #endif | ||
| 4654 | } else if (!BIT(inst, 22)) { | ||
| 4655 | for( i = 0; i < 16; i ++ ){ | ||
| 4656 | if(BIT(inst, i)){ | ||
| 4657 | //bus_read(32, addr, &ret); | ||
| 4658 | #if 0 | ||
| 4659 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4660 | if (fault) { | ||
| 4661 | goto MMU_EXCEPTION; | ||
| 4662 | } | ||
| 4663 | #endif | ||
| 4664 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4665 | if (fault) goto MMU_EXCEPTION; | ||
| 4666 | /* For armv5t, should enter thumb when bits[0] is non-zero. */ | ||
| 4667 | if(i == 15){ | ||
| 4668 | cpu->TFlag = ret & 0x1; | ||
| 4669 | ret &= 0xFFFFFFFE; | ||
| 4670 | //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret); | ||
| 4671 | } | ||
| 4672 | |||
| 4673 | cpu->Reg[i] = ret; | ||
| 4674 | addr += 4; | ||
| 4675 | if ((addr & 0xfff) == 0) { | ||
| 4676 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4677 | } else { | ||
| 4678 | phys_addr += 4; | ||
| 4679 | } | ||
| 4680 | } | ||
| 4681 | } | ||
| 4682 | } else if (BIT(inst, 22) && BIT(inst, 15)) { | ||
| 4683 | for( i = 0; i < 15; i ++ ){ | ||
| 4684 | if(BIT(inst, i)){ | ||
| 4685 | #if 0 | ||
| 4686 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4687 | if (fault) { | ||
| 4688 | goto MMU_EXCEPTION; | ||
| 4689 | } | ||
| 4690 | #endif | ||
| 4691 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4692 | //if (fault) goto MMU_EXCEPTION; | ||
| 4693 | cpu->Reg[i] = ret; | ||
| 4694 | addr += 4; | ||
| 4695 | if ((addr & 0xfff) == 0) { | ||
| 4696 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4697 | } else { | ||
| 4698 | phys_addr += 4; | ||
| 4699 | } | ||
| 4700 | } | ||
| 4701 | } | ||
| 4702 | |||
| 4703 | if (CurrentModeHasSPSR) { | ||
| 4704 | cpu->Cpsr = cpu->Spsr_copy; | ||
| 4705 | switch_mode(cpu, cpu->Cpsr & 0x1f); | ||
| 4706 | LOAD_NZCVT; | ||
| 4707 | } | ||
| 4708 | #if 0 | ||
| 4709 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4710 | if (fault) { | ||
| 4711 | goto MMU_EXCEPTION; | ||
| 4712 | } | ||
| 4713 | #endif | ||
| 4714 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4715 | if (fault) { | ||
| 4716 | goto MMU_EXCEPTION; | ||
| 4717 | } | ||
| 4718 | cpu->Reg[15] = ret; | ||
| 4719 | #if 0 | ||
| 4720 | addr += 4; | ||
| 4721 | phys_addr += 4; | ||
| 4722 | #endif | ||
| 4723 | } | ||
| 4724 | if (BIT(inst, 15)) { | ||
| 4725 | INC_PC(sizeof(ldst_inst)); | ||
| 4726 | goto DISPATCH; | ||
| 4727 | } | ||
| 4728 | } | ||
| 4729 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4730 | INC_PC(sizeof(ldst_inst)); | ||
| 4731 | FETCH_INST; | ||
| 4732 | GOTO_NEXT_INST; | ||
| 4733 | } | ||
| 4734 | SXTH_INST: | ||
| 4735 | { | ||
| 4736 | INC_ICOUNTER; | ||
| 4737 | sxth_inst *inst_cream = (sxth_inst *)inst_base->component; | ||
| 4738 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4739 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); | ||
| 4740 | if (BIT(operand2, 15)) { | ||
| 4741 | operand2 |= 0xffff0000; | ||
| 4742 | } else { | ||
| 4743 | operand2 &= 0xffff; | ||
| 4744 | } | ||
| 4745 | RD = operand2; | ||
| 4746 | } | ||
| 4747 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4748 | INC_PC(sizeof(sxth_inst)); | ||
| 4749 | FETCH_INST; | ||
| 4750 | GOTO_NEXT_INST; | ||
| 4751 | } | ||
| 4752 | LDR_INST: | ||
| 4753 | { | ||
| 4754 | INC_ICOUNTER; | ||
| 4755 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4756 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4757 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4758 | if (fault) goto MMU_EXCEPTION; | ||
| 4759 | unsigned int value; | ||
| 4760 | //bus_read(32, addr, &value); | ||
| 4761 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4762 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | ||
| 4763 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4764 | else { | ||
| 4765 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); | ||
| 4766 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4767 | } | ||
| 4768 | if (BITS(inst_cream->inst, 12, 15) == 15) { | ||
| 4769 | /* For armv5t, should enter thumb when bits[0] is non-zero. */ | ||
| 4770 | cpu->TFlag = value & 0x1; | ||
| 4771 | cpu->Reg[15] &= 0xFFFFFFFE; | ||
| 4772 | INC_PC(sizeof(ldst_inst)); | ||
| 4773 | goto DISPATCH; | ||
| 4774 | } | ||
| 4775 | //} | ||
| 4776 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4777 | INC_PC(sizeof(ldst_inst)); | ||
| 4778 | FETCH_INST; | ||
| 4779 | GOTO_NEXT_INST; | ||
| 4780 | } | ||
| 4781 | LDRCOND_INST: | ||
| 4782 | { | ||
| 4783 | INC_ICOUNTER; | ||
| 4784 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 4785 | if (CondPassed(cpu, inst_base->cond)) { | ||
| 4786 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4787 | if (fault) goto MMU_EXCEPTION; | ||
| 4788 | unsigned int value; | ||
| 4789 | //bus_read(32, addr, &value); | ||
| 4790 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4791 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | ||
| 4792 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4793 | else { | ||
| 4794 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); | ||
| 4795 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4796 | } | 4336 | } |
| 4797 | 4337 | ||
| 4798 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4338 | cpu->Reg[i] = ret; |
| 4799 | /* For armv5t, should enter thumb when bits[0] is non-zero. */ | 4339 | addr += 4; |
| 4800 | cpu->TFlag = value & 0x1; | 4340 | if ((addr & 0xfff) == 0) { |
| 4801 | cpu->Reg[15] &= 0xFFFFFFFE; | 4341 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4802 | INC_PC(sizeof(ldst_inst)); | 4342 | } else { |
| 4803 | goto DISPATCH; | 4343 | phys_addr += 4; |
| 4804 | } | 4344 | } |
| 4805 | } | 4345 | } |
| 4806 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4346 | } |
| 4807 | INC_PC(sizeof(ldst_inst)); | 4347 | } else if (BIT(inst, 22) && BIT(inst, 15)) { |
| 4808 | FETCH_INST; | 4348 | for( i = 0; i < 15; i ++ ){ |
| 4809 | GOTO_NEXT_INST; | 4349 | if(BIT(inst, i)){ |
| 4810 | } | 4350 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4811 | UXTH_INST: | 4351 | cpu->Reg[i] = ret; |
| 4812 | { | 4352 | addr += 4; |
| 4813 | INC_ICOUNTER; | 4353 | if ((addr & 0xfff) == 0) { |
| 4814 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; | 4354 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 4815 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4355 | } else { |
| 4816 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 4356 | phys_addr += 4; |
| 4817 | & 0xffff; | 4357 | } |
| 4818 | RD = operand2; | 4358 | } |
| 4819 | } | 4359 | } |
| 4820 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4360 | |
| 4821 | INC_PC(sizeof(uxth_inst)); | 4361 | if (CurrentModeHasSPSR) { |
| 4822 | FETCH_INST; | 4362 | cpu->Cpsr = cpu->Spsr_copy; |
| 4823 | GOTO_NEXT_INST; | 4363 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4824 | } | 4364 | LOAD_NZCVT; |
| 4825 | UXTAH_INST: | 4365 | } |
| 4826 | { | 4366 | |
| 4827 | INC_ICOUNTER; | 4367 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); |
| 4828 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; | 4368 | if (fault) { |
| 4829 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4369 | goto MMU_EXCEPTION; |
| 4830 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 4370 | } |
| 4831 | & 0xffff; | 4371 | cpu->Reg[15] = ret; |
| 4832 | RD = RN + operand2; | 4372 | } |
| 4833 | if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { | 4373 | if (BIT(inst, 15)) { |
| 4834 | DEBUG_LOG(ARM11, "in line %d\n", __LINE__); | 4374 | INC_PC(sizeof(ldst_inst)); |
| 4835 | CITRA_IGNORE_EXIT(-1); | 4375 | goto DISPATCH; |
| 4836 | } | 4376 | } |
| 4837 | } | 4377 | } |
| 4838 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4378 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4839 | INC_PC(sizeof(uxtah_inst)); | 4379 | INC_PC(sizeof(ldst_inst)); |
| 4840 | FETCH_INST; | 4380 | FETCH_INST; |
| 4841 | GOTO_NEXT_INST; | 4381 | GOTO_NEXT_INST; |
| 4842 | } | 4382 | } |
| 4843 | LDRB_INST: | 4383 | SXTH_INST: |
| 4844 | { | 4384 | { |
| 4845 | INC_ICOUNTER; | 4385 | sxth_inst *inst_cream = (sxth_inst *)inst_base->component; |
| 4846 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4386 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4847 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4387 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); |
| 4848 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4388 | if (BIT(operand2, 15)) { |
| 4849 | if (fault) goto MMU_EXCEPTION; | 4389 | operand2 |= 0xffff0000; |
| 4850 | unsigned int value; | 4390 | } else { |
| 4851 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 4391 | operand2 &= 0xffff; |
| 4852 | if (fault) goto MMU_EXCEPTION; | 4392 | } |
| 4853 | //bus_read(8, addr, &value); | 4393 | RD = operand2; |
| 4854 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4394 | } |
| 4855 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4395 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4856 | INC_PC(sizeof(ldst_inst)); | 4396 | INC_PC(sizeof(sxth_inst)); |
| 4857 | goto DISPATCH; | 4397 | FETCH_INST; |
| 4858 | } | 4398 | GOTO_NEXT_INST; |
| 4859 | } | 4399 | } |
| 4860 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4400 | LDR_INST: |
| 4861 | INC_PC(sizeof(ldst_inst)); | 4401 | { |
| 4862 | FETCH_INST; | 4402 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4863 | GOTO_NEXT_INST; | 4403 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4864 | } | 4404 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4865 | LDRBT_INST: | 4405 | if (fault) goto MMU_EXCEPTION; |
| 4866 | { | 4406 | unsigned int value; |
| 4867 | INC_ICOUNTER; | 4407 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 4868 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4408 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 4869 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4409 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4870 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4410 | else { |
| 4871 | if (fault) goto MMU_EXCEPTION; | 4411 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); |
| 4872 | unsigned int value; | 4412 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4873 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 4413 | } |
| 4874 | if (fault) goto MMU_EXCEPTION; | 4414 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4875 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4415 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4876 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4416 | cpu->TFlag = value & 0x1; |
| 4877 | INC_PC(sizeof(ldst_inst)); | 4417 | cpu->Reg[15] &= 0xFFFFFFFE; |
| 4878 | goto DISPATCH; | 4418 | INC_PC(sizeof(ldst_inst)); |
| 4879 | } | 4419 | goto DISPATCH; |
| 4880 | } | 4420 | } |
| 4881 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4421 | //} |
| 4882 | INC_PC(sizeof(ldst_inst)); | 4422 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4883 | FETCH_INST; | 4423 | INC_PC(sizeof(ldst_inst)); |
| 4884 | GOTO_NEXT_INST; | 4424 | FETCH_INST; |
| 4885 | } | 4425 | GOTO_NEXT_INST; |
| 4886 | LDRD_INST: | 4426 | } |
| 4887 | { | 4427 | LDRCOND_INST: |
| 4888 | INC_ICOUNTER; | 4428 | { |
| 4889 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4429 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4890 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4430 | if (CondPassed(cpu, inst_base->cond)) { |
| 4891 | /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */ | 4431 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4892 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4432 | if (fault) goto MMU_EXCEPTION; |
| 4893 | if (fault) goto MMU_EXCEPTION; | 4433 | unsigned int value; |
| 4894 | uint32_t rear_phys_addr; | 4434 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 4895 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); | 4435 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 4896 | if(fault){ | 4436 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4897 | ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n"); | 4437 | else { |
| 4898 | CITRA_IGNORE_EXIT(-1); | 4438 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); |
| 4899 | goto MMU_EXCEPTION; | 4439 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4900 | } | 4440 | } |
| 4901 | unsigned int value; | 4441 | |
| 4902 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 4442 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4903 | if (fault) goto MMU_EXCEPTION; | 4443 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4904 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4444 | cpu->TFlag = value & 0x1; |
| 4905 | fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); | 4445 | cpu->Reg[15] &= 0xFFFFFFFE; |
| 4906 | if (fault) goto MMU_EXCEPTION; | 4446 | INC_PC(sizeof(ldst_inst)); |
| 4907 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; | 4447 | goto DISPATCH; |
| 4908 | /* No dispatch since this operation should not modify R15 */ | 4448 | } |
| 4909 | } | 4449 | } |
| 4910 | cpu->Reg[15] += 4; | 4450 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4911 | INC_PC(sizeof(ldst_inst)); | 4451 | INC_PC(sizeof(ldst_inst)); |
| 4912 | FETCH_INST; | 4452 | FETCH_INST; |
| 4913 | GOTO_NEXT_INST; | 4453 | GOTO_NEXT_INST; |
| 4914 | } | 4454 | } |
| 4915 | 4455 | UXTH_INST: | |
| 4916 | LDREX_INST: | 4456 | { |
| 4917 | { | 4457 | uxth_inst *inst_cream = (uxth_inst *)inst_base->component; |
| 4918 | INC_ICOUNTER; | 4458 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4919 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4459 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) |
| 4920 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4460 | & 0xffff; |
| 4921 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 4461 | RD = operand2; |
| 4922 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4462 | } |
| 4923 | if (fault) goto MMU_EXCEPTION; | 4463 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4924 | unsigned int value; | 4464 | INC_PC(sizeof(uxth_inst)); |
| 4925 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 4465 | FETCH_INST; |
| 4926 | if (fault) goto MMU_EXCEPTION; | 4466 | GOTO_NEXT_INST; |
| 4927 | 4467 | } | |
| 4928 | add_exclusive_addr(cpu, phys_addr); | 4468 | UXTAH_INST: |
| 4929 | cpu->exclusive_state = 1; | 4469 | { |
| 4930 | 4470 | uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; | |
| 4931 | //bus_read(32, addr, &value); | 4471 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4932 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4472 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) |
| 4933 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4473 | & 0xffff; |
| 4934 | INC_PC(sizeof(ldst_inst)); | 4474 | RD = RN + operand2; |
| 4935 | goto DISPATCH; | 4475 | if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { |
| 4936 | } | 4476 | LOG_ERROR(Core_ARM11, "invalid operands for UXTAH"); |
| 4937 | } | 4477 | CITRA_IGNORE_EXIT(-1); |
| 4938 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4478 | } |
| 4939 | INC_PC(sizeof(ldst_inst)); | 4479 | } |
| 4940 | FETCH_INST; | 4480 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4941 | GOTO_NEXT_INST; | 4481 | INC_PC(sizeof(uxtah_inst)); |
| 4942 | } | 4482 | FETCH_INST; |
| 4943 | LDREXB_INST: | 4483 | GOTO_NEXT_INST; |
| 4944 | { | 4484 | } |
| 4945 | INC_ICOUNTER; | 4485 | LDRB_INST: |
| 4946 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4486 | { |
| 4947 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4487 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4948 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 4488 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4949 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 4489 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4950 | if (fault) goto MMU_EXCEPTION; | 4490 | if (fault) goto MMU_EXCEPTION; |
| 4951 | unsigned int value; | 4491 | unsigned int value; |
| 4952 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 4492 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 4953 | if (fault) goto MMU_EXCEPTION; | 4493 | if (fault) goto MMU_EXCEPTION; |
| 4954 | 4494 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | |
| 4955 | add_exclusive_addr(cpu, phys_addr); | 4495 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4956 | cpu->exclusive_state = 1; | 4496 | INC_PC(sizeof(ldst_inst)); |
| 4957 | 4497 | goto DISPATCH; | |
| 4958 | //bus_read(8, addr, &value); | 4498 | } |
| 4959 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4499 | } |
| 4960 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4500 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4961 | INC_PC(sizeof(ldst_inst)); | 4501 | INC_PC(sizeof(ldst_inst)); |
| 4962 | goto DISPATCH; | 4502 | FETCH_INST; |
| 4963 | } | 4503 | GOTO_NEXT_INST; |
| 4964 | } | 4504 | } |
| 4965 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4505 | LDRBT_INST: |
| 4966 | INC_PC(sizeof(ldst_inst)); | 4506 | { |
| 4967 | FETCH_INST; | 4507 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4968 | GOTO_NEXT_INST; | 4508 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4969 | } | 4509 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4970 | LDRH_INST: | 4510 | if (fault) goto MMU_EXCEPTION; |
| 4971 | { | 4511 | unsigned int value; |
| 4972 | INC_ICOUNTER; | 4512 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 4973 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4513 | if (fault) goto MMU_EXCEPTION; |
| 4974 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4514 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4975 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4515 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4976 | if (fault) goto MMU_EXCEPTION; | 4516 | INC_PC(sizeof(ldst_inst)); |
| 4977 | unsigned int value = 0; | 4517 | goto DISPATCH; |
| 4978 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | 4518 | } |
| 4979 | // fault = interpreter_read_memory(addr, value, 32); | 4519 | } |
| 4980 | if (fault) goto MMU_EXCEPTION; | 4520 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4981 | //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) { | 4521 | INC_PC(sizeof(ldst_inst)); |
| 4982 | // value = 0xffffffff; | 4522 | FETCH_INST; |
| 4983 | //} | 4523 | GOTO_NEXT_INST; |
| 4984 | //bus_read(16, addr, &value); | 4524 | } |
| 4985 | // cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff; | 4525 | LDRD_INST: |
| 4986 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4526 | { |
| 4987 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4527 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4988 | INC_PC(sizeof(ldst_inst)); | 4528 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4989 | goto DISPATCH; | 4529 | // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) |
| 4990 | } | 4530 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 4991 | } | 4531 | if (fault) goto MMU_EXCEPTION; |
| 4992 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4532 | uint32_t rear_phys_addr; |
| 4993 | INC_PC(sizeof(ldst_inst)); | 4533 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); |
| 4994 | FETCH_INST; | 4534 | if(fault){ |
| 4995 | GOTO_NEXT_INST; | 4535 | LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr\n"); |
| 4996 | } | 4536 | CITRA_IGNORE_EXIT(-1); |
| 4997 | LDRSB_INST: | 4537 | goto MMU_EXCEPTION; |
| 4998 | { | 4538 | } |
| 4999 | INC_ICOUNTER; | 4539 | unsigned int value; |
| 5000 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4540 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 5001 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4541 | if (fault) goto MMU_EXCEPTION; |
| 5002 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4542 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5003 | if (fault) goto MMU_EXCEPTION; | 4543 | fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); |
| 5004 | unsigned int value; | 4544 | if (fault) goto MMU_EXCEPTION; |
| 5005 | // DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr); | 4545 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; |
| 5006 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 4546 | |
| 5007 | if (fault) goto MMU_EXCEPTION; | 4547 | // No dispatch since this operation should not modify R15 |
| 5008 | //bus_read(8, addr, &value); | 4548 | } |
| 5009 | if (BIT(value, 7)) { | 4549 | cpu->Reg[15] += 4; |
| 5010 | value |= 0xffffff00; | 4550 | INC_PC(sizeof(ldst_inst)); |
| 5011 | } | 4551 | FETCH_INST; |
| 5012 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4552 | GOTO_NEXT_INST; |
| 5013 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4553 | } |
| 5014 | INC_PC(sizeof(ldst_inst)); | 4554 | |
| 5015 | goto DISPATCH; | 4555 | LDREX_INST: |
| 5016 | } | 4556 | { |
| 5017 | } | 4557 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5018 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4558 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5019 | INC_PC(sizeof(ldst_inst)); | 4559 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 5020 | FETCH_INST; | 4560 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 5021 | GOTO_NEXT_INST; | 4561 | if (fault) goto MMU_EXCEPTION; |
| 5022 | } | 4562 | unsigned int value; |
| 5023 | LDRSH_INST: | 4563 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 5024 | { | 4564 | if (fault) goto MMU_EXCEPTION; |
| 5025 | INC_ICOUNTER; | 4565 | |
| 5026 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4566 | add_exclusive_addr(cpu, phys_addr); |
| 5027 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4567 | cpu->exclusive_state = 1; |
| 5028 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4568 | |
| 5029 | if (fault) goto MMU_EXCEPTION; | 4569 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5030 | unsigned int value; | 4570 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5031 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | 4571 | INC_PC(sizeof(ldst_inst)); |
| 5032 | if (fault) goto MMU_EXCEPTION; | 4572 | goto DISPATCH; |
| 5033 | //bus_read(16, addr, &value); | 4573 | } |
| 5034 | if (BIT(value, 15)) { | 4574 | } |
| 5035 | value |= 0xffff0000; | 4575 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5036 | } | 4576 | INC_PC(sizeof(ldst_inst)); |
| 5037 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4577 | FETCH_INST; |
| 5038 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4578 | GOTO_NEXT_INST; |
| 5039 | INC_PC(sizeof(ldst_inst)); | 4579 | } |
| 5040 | goto DISPATCH; | 4580 | LDREXB_INST: |
| 5041 | } | 4581 | { |
| 5042 | } | 4582 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5043 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4583 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5044 | INC_PC(sizeof(ldst_inst)); | 4584 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 5045 | FETCH_INST; | 4585 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 5046 | GOTO_NEXT_INST; | 4586 | if (fault) goto MMU_EXCEPTION; |
| 5047 | } | 4587 | unsigned int value; |
| 5048 | LDRT_INST: | 4588 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 5049 | { | 4589 | if (fault) goto MMU_EXCEPTION; |
| 5050 | INC_ICOUNTER; | 4590 | |
| 5051 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4591 | add_exclusive_addr(cpu, phys_addr); |
| 5052 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4592 | cpu->exclusive_state = 1; |
| 5053 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4593 | |
| 5054 | if (fault) goto MMU_EXCEPTION; | 4594 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5055 | unsigned int value; | 4595 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5056 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 4596 | INC_PC(sizeof(ldst_inst)); |
| 5057 | if (fault) goto MMU_EXCEPTION; | 4597 | goto DISPATCH; |
| 5058 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4598 | } |
| 5059 | 4599 | } | |
| 5060 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | 4600 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5061 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4601 | INC_PC(sizeof(ldst_inst)); |
| 5062 | else | 4602 | FETCH_INST; |
| 5063 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; | 4603 | GOTO_NEXT_INST; |
| 5064 | 4604 | } | |
| 5065 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4605 | LDRH_INST: |
| 5066 | INC_PC(sizeof(ldst_inst)); | 4606 | { |
| 5067 | goto DISPATCH; | 4607 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5068 | } | 4608 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5069 | } | 4609 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 5070 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4610 | if (fault) goto MMU_EXCEPTION; |
| 5071 | INC_PC(sizeof(ldst_inst)); | 4611 | unsigned int value = 0; |
| 5072 | FETCH_INST; | 4612 | fault = interpreter_read_memory(addr, phys_addr, value, 16); |
| 5073 | GOTO_NEXT_INST; | 4613 | if (fault) goto MMU_EXCEPTION; |
| 5074 | } | 4614 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5075 | MCR_INST: | 4615 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5076 | { | 4616 | INC_PC(sizeof(ldst_inst)); |
| 5077 | INC_ICOUNTER; | 4617 | goto DISPATCH; |
| 5078 | /* NOT IMPL */ | 4618 | } |
| 5079 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; | 4619 | } |
| 5080 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4620 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5081 | unsigned int inst = inst_cream->inst; | 4621 | INC_PC(sizeof(ldst_inst)); |
| 5082 | if (inst_cream->Rd == 15) { | 4622 | FETCH_INST; |
| 5083 | DEBUG_MSG; | 4623 | GOTO_NEXT_INST; |
| 5084 | } else { | 4624 | } |
| 5085 | if (inst_cream->cp_num == 15) { | 4625 | LDRSB_INST: |
| 5086 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { | 4626 | { |
| 5087 | //LET(RD, CONST(0x0007b000)); | 4627 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5088 | //LET(RD, CONST(0x410FB760)); | 4628 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5089 | //LET(CP15_MAIN_ID, R(RD)); | 4629 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 5090 | CP15_REG(CP15_MAIN_ID) = RD; | 4630 | if (fault) goto MMU_EXCEPTION; |
| 5091 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { | 4631 | unsigned int value; |
| 5092 | //LET(RD, R(CP15_CONTROL)); | 4632 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 5093 | CP15_REG(CP15_AUXILIARY_CONTROL) = RD; | 4633 | if (fault) goto MMU_EXCEPTION; |
| 5094 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { | 4634 | if (BIT(value, 7)) { |
| 5095 | //LET(RD, R(CP15_CONTROL)); | 4635 | value |= 0xffffff00; |
| 5096 | CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; | 4636 | } |
| 5097 | } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { | 4637 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5098 | //LET(CP15_CONTROL, R(RD)); | 4638 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5099 | CP15_REG(CP15_CONTROL) = RD; | 4639 | INC_PC(sizeof(ldst_inst)); |
| 5100 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { | 4640 | goto DISPATCH; |
| 5101 | //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD)); | 4641 | } |
| 5102 | CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; | 4642 | } |
| 5103 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { | 4643 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5104 | //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD)); | 4644 | INC_PC(sizeof(ldst_inst)); |
| 5105 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; | 4645 | FETCH_INST; |
| 5106 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { | 4646 | GOTO_NEXT_INST; |
| 5107 | //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD)); | 4647 | } |
| 5108 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; | 4648 | LDRSH_INST: |
| 5109 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { | 4649 | { |
| 5110 | //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD)); | 4650 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5111 | CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; | 4651 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5112 | } else if(CRn == MMU_CACHE_OPS){ | 4652 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 5113 | //SKYEYE_WARNING("cache operation have not implemented.\n"); | 4653 | if (fault) goto MMU_EXCEPTION; |
| 5114 | } else if(CRn == MMU_TLB_OPS){ | 4654 | unsigned int value; |
| 5115 | switch (CRm) { | 4655 | fault = interpreter_read_memory(addr, phys_addr, value, 16); |
| 5116 | case 5: /* ITLB */ | 4656 | if (fault) goto MMU_EXCEPTION; |
| 5117 | switch(OPCODE_2){ | 4657 | if (BIT(value, 15)) { |
| 5118 | case 0: /* invalidate all */ | 4658 | value |= 0xffff0000; |
| 5119 | //invalidate_all_tlb(state); | 4659 | } |
| 5120 | DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n"); | 4660 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5121 | //remove_tlb(INSN_TLB); | 4661 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5122 | //erase_all(core, INSN_TLB); | 4662 | INC_PC(sizeof(ldst_inst)); |
| 5123 | break; | 4663 | goto DISPATCH; |
| 5124 | case 1: /* invalidate by MVA */ | 4664 | } |
| 5125 | //invalidate_by_mva(state, value); | 4665 | } |
| 5126 | //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n"); | 4666 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5127 | //remove_tlb_by_mva(RD, INSN_TLB); | 4667 | INC_PC(sizeof(ldst_inst)); |
| 5128 | //erase_by_mva(core, RD, INSN_TLB); | 4668 | FETCH_INST; |
| 5129 | break; | 4669 | GOTO_NEXT_INST; |
| 5130 | case 2: /* invalidate by asid */ | 4670 | } |
| 5131 | //invalidate_by_asid(state, value); | 4671 | LDRT_INST: |
| 5132 | //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n"); | 4672 | { |
| 5133 | //erase_by_asid(core, RD, INSN_TLB); | 4673 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5134 | break; | 4674 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5135 | default: | 4675 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); |
| 5136 | break; | 4676 | if (fault) goto MMU_EXCEPTION; |
| 5137 | } | 4677 | unsigned int value; |
| 5138 | 4678 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | |
| 5139 | break; | 4679 | if (fault) goto MMU_EXCEPTION; |
| 5140 | case 6: /* DTLB */ | 4680 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5141 | switch(OPCODE_2){ | 4681 | |
| 5142 | case 0: /* invalidate all */ | 4682 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 5143 | //invalidate_all_tlb(state); | 4683 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 5144 | //remove_tlb(DATA_TLB); | 4684 | else |
| 5145 | //erase_all(core, DATA_TLB); | 4685 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ; |
| 5146 | DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n"); | 4686 | |
| 5147 | break; | 4687 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 5148 | case 1: /* invalidate by MVA */ | 4688 | INC_PC(sizeof(ldst_inst)); |
| 5149 | //invalidate_by_mva(state, value); | 4689 | goto DISPATCH; |
| 5150 | //remove_tlb_by_mva(RD, DATA_TLB); | 4690 | } |
| 5151 | //erase_by_mva(core, RD, DATA_TLB); | 4691 | } |
| 5152 | //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n"); | 4692 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5153 | break; | 4693 | INC_PC(sizeof(ldst_inst)); |
| 5154 | case 2: /* invalidate by asid */ | 4694 | FETCH_INST; |
| 5155 | //invalidate_by_asid(state, value); | 4695 | GOTO_NEXT_INST; |
| 5156 | //remove_tlb_by_asid(RD, DATA_TLB); | 4696 | } |
| 5157 | //erase_by_asid(core, RD, DATA_TLB); | 4697 | MCR_INST: |
| 5158 | //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n"); | 4698 | { |
| 5159 | break; | 4699 | mcr_inst *inst_cream = (mcr_inst *)inst_base->component; |
| 5160 | default: | 4700 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5161 | break; | 4701 | unsigned int inst = inst_cream->inst; |
| 5162 | } | 4702 | if (inst_cream->Rd == 15) { |
| 5163 | break; | 4703 | DEBUG_MSG; |
| 5164 | case 7: /* UNIFILED TLB */ | 4704 | } else { |
| 5165 | switch(OPCODE_2){ | 4705 | if (inst_cream->cp_num == 15) { |
| 5166 | case 0: /* invalidate all */ | 4706 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { |
| 5167 | //invalidate_all_tlb(state); | 4707 | CP15_REG(CP15_MAIN_ID) = RD; |
| 5168 | //erase_all(core, INSN_TLB); | 4708 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { |
| 5169 | //erase_all(core, DATA_TLB); | 4709 | CP15_REG(CP15_AUXILIARY_CONTROL) = RD; |
| 5170 | //remove_tlb(DATA_TLB); | 4710 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { |
| 5171 | //remove_tlb(INSN_TLB); | 4711 | CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD; |
| 5172 | //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n"); | 4712 | } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) { |
| 5173 | break; | 4713 | CP15_REG(CP15_CONTROL) = RD; |
| 5174 | case 1: /* invalidate by MVA */ | 4714 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { |
| 5175 | //invalidate_by_mva(state, value); | 4715 | CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD; |
| 5176 | //erase_by_mva(core, RD, DATA_TLB); | 4716 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { |
| 5177 | //erase_by_mva(core, RD, INSN_TLB); | 4717 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD; |
| 5178 | DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n"); | 4718 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) { |
| 5179 | break; | 4719 | CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD; |
| 5180 | case 2: /* invalidate by asid */ | 4720 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) { |
| 5181 | //invalidate_by_asid(state, value); | 4721 | CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD; |
| 5182 | //erase_by_asid(core, RD, DATA_TLB); | 4722 | } else if(CRn == MMU_CACHE_OPS){ |
| 5183 | //erase_by_asid(core, RD, INSN_TLB); | 4723 | //LOG_WARNING(Core_ARM11, "cache operations have not implemented."); |
| 5184 | DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n"); | 4724 | } else if(CRn == MMU_TLB_OPS){ |
| 5185 | break; | 4725 | switch (CRm) { |
| 5186 | default: | 4726 | case 5: // ITLB |
| 5187 | break; | 4727 | switch(OPCODE_2) { |
| 5188 | } | 4728 | case 0: // Invalidate all |
| 5189 | break; | 4729 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all"); |
| 5190 | default: | 4730 | break; |
| 5191 | break; | 4731 | case 1: // Invalidate by MVA |
| 5192 | } | 4732 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by mva"); |
| 5193 | } else if(CRn == MMU_PID){ | 4733 | break; |
| 5194 | if(OPCODE_2 == 0) | 4734 | case 2: // Invalidate by asid |
| 5195 | CP15_REG(CP15_PID) = RD; | 4735 | LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by asid"); |
| 5196 | else if(OPCODE_2 == 1) | 4736 | break; |
| 5197 | CP15_REG(CP15_CONTEXT_ID) = RD; | 4737 | default: |
| 5198 | else if(OPCODE_2 == 3){ | 4738 | break; |
| 5199 | CP15_REG(CP15_THREAD_URO) = RD; | 4739 | } |
| 5200 | } | 4740 | |
| 5201 | else{ | 4741 | break; |
| 5202 | printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn); | 4742 | case 6: // DTLB |
| 5203 | } | 4743 | switch(OPCODE_2){ |
| 5204 | 4744 | case 0: // Invalidate all | |
| 5205 | } else { | 4745 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all"); |
| 5206 | DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); | 4746 | break; |
| 5207 | } | 4747 | case 1: // Invalidate by MVA |
| 5208 | } | 4748 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by mva"); |
| 5209 | } | 4749 | break; |
| 5210 | } | 4750 | case 2: // Invalidate by asid |
| 5211 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4751 | LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by asid"); |
| 5212 | INC_PC(sizeof(mcr_inst)); | 4752 | break; |
| 5213 | FETCH_INST; | 4753 | default: |
| 5214 | GOTO_NEXT_INST; | 4754 | break; |
| 5215 | } | 4755 | } |
| 5216 | MCRR_INST: | 4756 | break; |
| 5217 | MLA_INST: | 4757 | case 7: // UNIFILED TLB |
| 5218 | { | 4758 | switch(OPCODE_2){ |
| 5219 | INC_ICOUNTER; | 4759 | case 0: // invalidate all |
| 5220 | mla_inst *inst_cream = (mla_inst *)inst_base->component; | 4760 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate all"); |
| 5221 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4761 | break; |
| 5222 | uint64_t rm = RM; | 4762 | case 1: // Invalidate by MVA |
| 5223 | uint64_t rs = RS; | 4763 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva"); |
| 5224 | uint64_t rn = RN; | 4764 | break; |
| 5225 | if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { | 4765 | case 2: // Invalidate by asid |
| 5226 | DEBUG_LOG(ARM11, "in __line__\n", __LINE__); | 4766 | LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid"); |
| 5227 | CITRA_IGNORE_EXIT(-1); | 4767 | break; |
| 5228 | } | 4768 | default: |
| 5229 | // RD = dst = RM * RS + RN; | 4769 | break; |
| 5230 | RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); | 4770 | } |
| 5231 | if (inst_cream->S) { | 4771 | break; |
| 5232 | UPDATE_NFLAG(dst); | 4772 | default: |
| 5233 | UPDATE_ZFLAG(dst); | 4773 | break; |
| 5234 | } | 4774 | } |
| 5235 | if (inst_cream->Rd == 15) { | 4775 | } else if(CRn == MMU_PID) { |
| 5236 | INC_PC(sizeof(mla_inst)); | 4776 | if(OPCODE_2 == 0) |
| 5237 | goto DISPATCH; | 4777 | CP15_REG(CP15_PID) = RD; |
| 5238 | } | 4778 | else if(OPCODE_2 == 1) |
| 5239 | } | 4779 | CP15_REG(CP15_CONTEXT_ID) = RD; |
| 5240 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4780 | else if(OPCODE_2 == 3) { |
| 5241 | INC_PC(sizeof(mla_inst)); | 4781 | CP15_REG(CP15_THREAD_URO) = RD; |
| 5242 | FETCH_INST; | 4782 | } else { |
| 5243 | GOTO_NEXT_INST; | 4783 | LOG_ERROR(Core_ARM11, "mmu_mcr wrote UNKNOWN - reg %d", CRn); |
| 5244 | } | 4784 | } |
| 5245 | MOV_INST: | 4785 | } else { |
| 5246 | { | 4786 | LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2); |
| 5247 | // DEBUG_LOG(ARM11, "mov inst\n"); | 4787 | } |
| 5248 | // DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]); | 4788 | } |
| 5249 | // debug_function(cpu); | 4789 | } |
| 5250 | // cpu->icount ++; | 4790 | } |
| 5251 | INC_ICOUNTER; | 4791 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5252 | mov_inst *inst_cream = (mov_inst *)inst_base->component; | 4792 | INC_PC(sizeof(mcr_inst)); |
| 5253 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4793 | FETCH_INST; |
| 5254 | RD = dst = SHIFTER_OPERAND; | 4794 | GOTO_NEXT_INST; |
| 5255 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4795 | } |
| 5256 | /* cpsr = spsr */ | 4796 | MCRR_INST: |
| 5257 | if (CurrentModeHasSPSR) { | 4797 | MLA_INST: |
| 5258 | cpu->Cpsr = cpu->Spsr_copy; | 4798 | { |
| 5259 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4799 | mla_inst *inst_cream = (mla_inst *)inst_base->component; |
| 5260 | LOAD_NZCVT; | 4800 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5261 | } | 4801 | uint64_t rm = RM; |
| 5262 | } else if (inst_cream->S) { | 4802 | uint64_t rs = RS; |
| 5263 | UPDATE_NFLAG(dst); | 4803 | uint64_t rn = RN; |
| 5264 | UPDATE_ZFLAG(dst); | 4804 | if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) { |
| 5265 | UPDATE_CFLAG_WITH_SC; | 4805 | LOG_ERROR(Core_ARM11, "invalid operands for MLA"); |
| 5266 | } | 4806 | CITRA_IGNORE_EXIT(-1); |
| 5267 | if (inst_cream->Rd == 15) { | 4807 | } |
| 5268 | INC_PC(sizeof(mov_inst)); | 4808 | RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); |
| 5269 | goto DISPATCH; | 4809 | if (inst_cream->S) { |
| 5270 | } | 4810 | UPDATE_NFLAG(dst); |
| 5271 | // return; | 4811 | UPDATE_ZFLAG(dst); |
| 5272 | } | 4812 | } |
| 5273 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4813 | if (inst_cream->Rd == 15) { |
| 5274 | INC_PC(sizeof(mov_inst)); | 4814 | INC_PC(sizeof(mla_inst)); |
| 5275 | FETCH_INST; | 4815 | goto DISPATCH; |
| 5276 | GOTO_NEXT_INST; | 4816 | } |
| 5277 | } | 4817 | } |
| 5278 | MRC_INST: | 4818 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5279 | { | 4819 | INC_PC(sizeof(mla_inst)); |
| 5280 | INC_ICOUNTER; | 4820 | FETCH_INST; |
| 5281 | /* NOT IMPL */ | 4821 | GOTO_NEXT_INST; |
| 5282 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; | 4822 | } |
| 5283 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4823 | MOV_INST: |
| 5284 | unsigned int inst = inst_cream->inst; | 4824 | { |
| 5285 | if (inst_cream->Rd == 15) { | 4825 | mov_inst *inst_cream = (mov_inst *)inst_base->component; |
| 5286 | DEBUG_MSG; | 4826 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5287 | } | 4827 | RD = dst = SHIFTER_OPERAND; |
| 5288 | if (inst_cream->inst == 0xeef04a10) { | 4828 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5289 | /* undefined instruction fmrx */ | 4829 | if (CurrentModeHasSPSR) { |
| 5290 | RD = 0x20000000; | 4830 | cpu->Cpsr = cpu->Spsr_copy; |
| 5291 | CITRA_IGNORE_EXIT(-1); | 4831 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 5292 | goto END; | 4832 | LOAD_NZCVT; |
| 5293 | } else { | 4833 | } |
| 5294 | if (inst_cream->cp_num == 15) { | 4834 | } else if (inst_cream->S) { |
| 5295 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { | 4835 | UPDATE_NFLAG(dst); |
| 5296 | //LET(RD, CONST(0x0007b000)); | 4836 | UPDATE_ZFLAG(dst); |
| 5297 | //LET(RD, CONST(0x410FB760)); | 4837 | UPDATE_CFLAG_WITH_SC; |
| 5298 | //LET(RD, R(CP15_MAIN_ID)); | 4838 | } |
| 5299 | RD = cpu->CP15[CP15(CP15_MAIN_ID)]; | 4839 | if (inst_cream->Rd == 15) { |
| 5300 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { | 4840 | INC_PC(sizeof(mov_inst)); |
| 5301 | //LET(RD, R(CP15_CONTROL)); | 4841 | goto DISPATCH; |
| 5302 | RD = cpu->CP15[CP15(CP15_CONTROL)]; | 4842 | } |
| 5303 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { | 4843 | } |
| 5304 | //LET(RD, R(CP15_CONTROL)); | 4844 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5305 | RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; | 4845 | INC_PC(sizeof(mov_inst)); |
| 5306 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { | 4846 | FETCH_INST; |
| 5307 | //LET(RD, R(CP15_CONTROL)); | 4847 | GOTO_NEXT_INST; |
| 5308 | RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; | 4848 | } |
| 5309 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { | 4849 | MRC_INST: |
| 5310 | //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL)); | 4850 | { |
| 5311 | RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; | 4851 | mrc_inst *inst_cream = (mrc_inst *)inst_base->component; |
| 5312 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { | 4852 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5313 | //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0)); | 4853 | unsigned int inst = inst_cream->inst; |
| 5314 | RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; | 4854 | if (inst_cream->Rd == 15) { |
| 5315 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { | 4855 | DEBUG_MSG; |
| 5316 | //LET(RD, R(CP15_FAULT_STATUS)); | 4856 | } |
| 5317 | RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; | 4857 | if (inst_cream->inst == 0xeef04a10) { |
| 5318 | } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { | 4858 | // Undefined instruction fmrx |
| 5319 | //LET(RD, R(CP15_FAULT_ADDRESS)); | 4859 | RD = 0x20000000; |
| 5320 | RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; | 4860 | CITRA_IGNORE_EXIT(-1); |
| 5321 | } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { | 4861 | goto END; |
| 5322 | //LET(RD, R(CP15_CACHE_TYPE)); | 4862 | } else { |
| 5323 | RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; | 4863 | if (inst_cream->cp_num == 15) { |
| 5324 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { | 4864 | if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) { |
| 5325 | //LET(RD, R(CP15_INSTR_FAULT_STATUS)); | 4865 | RD = cpu->CP15[CP15(CP15_MAIN_ID)]; |
| 5326 | RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; | 4866 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) { |
| 5327 | } else if (CRn == 13) { | 4867 | RD = cpu->CP15[CP15(CP15_CONTROL)]; |
| 5328 | if(OPCODE_2 == 0) | 4868 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) { |
| 5329 | RD = CP15_REG(CP15_PID); | 4869 | RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)]; |
| 5330 | else if(OPCODE_2 == 1) | 4870 | } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) { |
| 5331 | RD = CP15_REG(CP15_CONTEXT_ID); | 4871 | RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)]; |
| 5332 | else if(OPCODE_2 == 3){ | 4872 | } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) { |
| 5333 | RD = Memory::KERNEL_MEMORY_VADDR; | 4873 | RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)]; |
| 5334 | } | 4874 | } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) { |
| 5335 | else{ | 4875 | RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)]; |
| 5336 | printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn); | 4876 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) { |
| 5337 | } | 4877 | RD = cpu->CP15[CP15(CP15_FAULT_STATUS)]; |
| 5338 | } | 4878 | } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) { |
| 5339 | else { | 4879 | RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)]; |
| 5340 | DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); | 4880 | } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) { |
| 5341 | } | 4881 | RD = cpu->CP15[CP15(CP15_CACHE_TYPE)]; |
| 5342 | } | 4882 | } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) { |
| 5343 | //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2); | 4883 | RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)]; |
| 5344 | } | 4884 | } else if (CRn == 13) { |
| 5345 | } | 4885 | if(OPCODE_2 == 0) |
| 5346 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4886 | RD = CP15_REG(CP15_PID); |
| 5347 | INC_PC(sizeof(mrc_inst)); | 4887 | else if(OPCODE_2 == 1) |
| 5348 | FETCH_INST; | 4888 | RD = CP15_REG(CP15_CONTEXT_ID); |
| 5349 | GOTO_NEXT_INST; | 4889 | else if(OPCODE_2 == 3) { |
| 5350 | } | 4890 | RD = Memory::KERNEL_MEMORY_VADDR; |
| 5351 | MRRC_INST: | 4891 | } else { |
| 5352 | MRS_INST: | 4892 | LOG_ERROR(Core_ARM11, "mmu_mrr wrote UNKNOWN - reg %d", CRn); |
| 5353 | { | 4893 | } |
| 5354 | INC_ICOUNTER; | 4894 | } else { |
| 5355 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; | 4895 | LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2); |
| 5356 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4896 | } |
| 5357 | if (inst_cream->R) { | 4897 | } |
| 5358 | RD = cpu->Spsr_copy; | 4898 | } |
| 5359 | } else { | 4899 | } |
| 5360 | SAVE_NZCVT; | 4900 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5361 | RD = cpu->Cpsr; | 4901 | INC_PC(sizeof(mrc_inst)); |
| 5362 | } | 4902 | FETCH_INST; |
| 5363 | } | 4903 | GOTO_NEXT_INST; |
| 5364 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4904 | } |
| 5365 | INC_PC(sizeof(mrs_inst)); | 4905 | MRRC_INST: |
| 5366 | FETCH_INST; | 4906 | MRS_INST: |
| 5367 | GOTO_NEXT_INST; | 4907 | { |
| 5368 | } | 4908 | mrs_inst *inst_cream = (mrs_inst *)inst_base->component; |
| 5369 | MSR_INST: | 4909 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5370 | { | 4910 | if (inst_cream->R) { |
| 5371 | INC_ICOUNTER; | 4911 | RD = cpu->Spsr_copy; |
| 5372 | msr_inst *inst_cream = (msr_inst *)inst_base->component; | 4912 | } else { |
| 5373 | const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; | 4913 | SAVE_NZCVT; |
| 5374 | unsigned int inst = inst_cream->inst; | 4914 | RD = cpu->Cpsr; |
| 5375 | unsigned int operand; | 4915 | } |
| 5376 | 4916 | } | |
| 5377 | if (BIT(inst, 25)) { | 4917 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5378 | int rot_imm = BITS(inst, 8, 11) * 2; | 4918 | INC_PC(sizeof(mrs_inst)); |
| 5379 | //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm)); | 4919 | FETCH_INST; |
| 5380 | operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); | 4920 | GOTO_NEXT_INST; |
| 5381 | } else { | 4921 | } |
| 5382 | //operand = R(RM); | 4922 | MSR_INST: |
| 5383 | operand = cpu->Reg[BITS(inst, 0, 3)]; | 4923 | { |
| 5384 | } | 4924 | msr_inst *inst_cream = (msr_inst *)inst_base->component; |
| 5385 | uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) | 4925 | const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; |
| 5386 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); | 4926 | unsigned int inst = inst_cream->inst; |
| 5387 | uint32_t mask; | 4927 | unsigned int operand; |
| 5388 | if (!inst_cream->R) { | 4928 | |
| 5389 | if (InAPrivilegedMode(cpu)) { | 4929 | if (BIT(inst, 25)) { |
| 5390 | if ((operand & StateMask) != 0) { | 4930 | int rot_imm = BITS(inst, 8, 11) * 2; |
| 5391 | /* UNPREDICTABLE */ | 4931 | operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); |
| 5392 | DEBUG_MSG; | 4932 | } else { |
| 5393 | } else | 4933 | operand = cpu->Reg[BITS(inst, 0, 3)]; |
| 5394 | mask = byte_mask & (UserMask | PrivMask); | 4934 | } |
| 5395 | } else { | 4935 | uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) |
| 5396 | mask = byte_mask & UserMask; | 4936 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); |
| 5397 | } | 4937 | uint32_t mask; |
| 5398 | //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); | 4938 | if (!inst_cream->R) { |
| 5399 | SAVE_NZCVT; | 4939 | if (InAPrivilegedMode(cpu)) { |
| 5400 | 4940 | if ((operand & StateMask) != 0) { | |
| 5401 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); | 4941 | /// UNPREDICTABLE |
| 5402 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4942 | DEBUG_MSG; |
| 5403 | LOAD_NZCVT; | 4943 | } else |
| 5404 | } else { | 4944 | mask = byte_mask & (UserMask | PrivMask); |
| 5405 | if (CurrentModeHasSPSR) { | 4945 | } else { |
| 5406 | mask = byte_mask & (UserMask | PrivMask | StateMask); | 4946 | mask = byte_mask & UserMask; |
| 5407 | //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask)))); | 4947 | } |
| 5408 | cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); | 4948 | SAVE_NZCVT; |
| 5409 | } | 4949 | |
| 5410 | } | 4950 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); |
| 5411 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4951 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 5412 | INC_PC(sizeof(msr_inst)); | 4952 | LOAD_NZCVT; |
| 5413 | FETCH_INST; | 4953 | } else { |
| 5414 | GOTO_NEXT_INST; | 4954 | if (CurrentModeHasSPSR) { |
| 5415 | } | 4955 | mask = byte_mask & (UserMask | PrivMask | StateMask); |
| 5416 | MUL_INST: | 4956 | cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); |
| 5417 | { | 4957 | } |
| 5418 | INC_ICOUNTER; | 4958 | } |
| 5419 | mul_inst *inst_cream = (mul_inst *)inst_base->component; | 4959 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5420 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4960 | INC_PC(sizeof(msr_inst)); |
| 5421 | // RD = dst = SHIFTER_OPERAND; | 4961 | FETCH_INST; |
| 5422 | uint64_t rm = RM; | 4962 | GOTO_NEXT_INST; |
| 5423 | uint64_t rs = RS; | 4963 | } |
| 5424 | RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); | 4964 | MUL_INST: |
| 5425 | if (inst_cream->S) { | 4965 | { |
| 5426 | UPDATE_NFLAG(dst); | 4966 | mul_inst *inst_cream = (mul_inst *)inst_base->component; |
| 5427 | UPDATE_ZFLAG(dst); | 4967 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5428 | } | 4968 | uint64_t rm = RM; |
| 5429 | if (inst_cream->Rd == 15) { | 4969 | uint64_t rs = RS; |
| 5430 | INC_PC(sizeof(mul_inst)); | 4970 | RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); |
| 5431 | goto DISPATCH; | 4971 | if (inst_cream->S) { |
| 5432 | } | 4972 | UPDATE_NFLAG(dst); |
| 5433 | } | 4973 | UPDATE_ZFLAG(dst); |
| 5434 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4974 | } |
| 5435 | INC_PC(sizeof(mul_inst)); | 4975 | if (inst_cream->Rd == 15) { |
| 5436 | FETCH_INST; | 4976 | INC_PC(sizeof(mul_inst)); |
| 5437 | GOTO_NEXT_INST; | 4977 | goto DISPATCH; |
| 5438 | } | 4978 | } |
| 5439 | MVN_INST: | 4979 | } |
| 5440 | { | 4980 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5441 | INC_ICOUNTER; | 4981 | INC_PC(sizeof(mul_inst)); |
| 5442 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; | 4982 | FETCH_INST; |
| 5443 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4983 | GOTO_NEXT_INST; |
| 5444 | // RD = dst = (SHIFTER_OPERAND ^ 0xffffffff); | 4984 | } |
| 5445 | RD = dst = ~SHIFTER_OPERAND; | 4985 | MVN_INST: |
| 5446 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4986 | { |
| 5447 | /* cpsr = spsr */ | 4987 | mvn_inst *inst_cream = (mvn_inst *)inst_base->component; |
| 5448 | if (CurrentModeHasSPSR) { | 4988 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5449 | cpu->Cpsr = cpu->Spsr_copy; | 4989 | RD = dst = ~SHIFTER_OPERAND; |
| 5450 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4990 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5451 | LOAD_NZCVT; | 4991 | if (CurrentModeHasSPSR) { |
| 5452 | } | 4992 | cpu->Cpsr = cpu->Spsr_copy; |
| 5453 | } else if (inst_cream->S) { | 4993 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 5454 | UPDATE_NFLAG(dst); | 4994 | LOAD_NZCVT; |
| 5455 | UPDATE_ZFLAG(dst); | 4995 | } |
| 5456 | UPDATE_CFLAG_WITH_SC; | 4996 | } else if (inst_cream->S) { |
| 5457 | } | 4997 | UPDATE_NFLAG(dst); |
| 5458 | if (inst_cream->Rd == 15) { | 4998 | UPDATE_ZFLAG(dst); |
| 5459 | INC_PC(sizeof(mvn_inst)); | 4999 | UPDATE_CFLAG_WITH_SC; |
| 5460 | goto DISPATCH; | 5000 | } |
| 5461 | } | 5001 | if (inst_cream->Rd == 15) { |
| 5462 | } | 5002 | INC_PC(sizeof(mvn_inst)); |
| 5463 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5003 | goto DISPATCH; |
| 5464 | INC_PC(sizeof(mvn_inst)); | 5004 | } |
| 5465 | FETCH_INST; | 5005 | } |
| 5466 | GOTO_NEXT_INST; | 5006 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5467 | } | 5007 | INC_PC(sizeof(mvn_inst)); |
| 5468 | ORR_INST: | 5008 | FETCH_INST; |
| 5469 | { | 5009 | GOTO_NEXT_INST; |
| 5470 | INC_ICOUNTER; | 5010 | } |
| 5471 | orr_inst *inst_cream = (orr_inst *)inst_base->component; | 5011 | ORR_INST: |
| 5472 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5012 | { |
| 5473 | lop = RN; | 5013 | orr_inst *inst_cream = (orr_inst *)inst_base->component; |
| 5474 | rop = SHIFTER_OPERAND; | 5014 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5475 | // DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]); | 5015 | lop = RN; |
| 5476 | RD = dst = lop | rop; | 5016 | rop = SHIFTER_OPERAND; |
| 5477 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5017 | RD = dst = lop | rop; |
| 5478 | /* cpsr = spsr*/ | 5018 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5479 | if (CurrentModeHasSPSR) { | 5019 | if (CurrentModeHasSPSR) { |
| 5480 | cpu->Cpsr = cpu->Spsr_copy; | 5020 | cpu->Cpsr = cpu->Spsr_copy; |
| 5481 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5021 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 5482 | LOAD_NZCVT; | 5022 | LOAD_NZCVT; |
| 5483 | } | 5023 | } |
| 5484 | } else if (inst_cream->S) { | 5024 | } else if (inst_cream->S) { |
| 5485 | UPDATE_NFLAG(dst); | 5025 | UPDATE_NFLAG(dst); |
| 5486 | UPDATE_ZFLAG(dst); | 5026 | UPDATE_ZFLAG(dst); |
| 5487 | UPDATE_CFLAG_WITH_SC; | 5027 | UPDATE_CFLAG_WITH_SC; |
| 5488 | // UPDATE_CFLAG(dst, lop, rop); | 5028 | } |
| 5489 | } | 5029 | if (inst_cream->Rd == 15) { |
| 5490 | if (inst_cream->Rd == 15) { | 5030 | INC_PC(sizeof(orr_inst)); |
| 5491 | INC_PC(sizeof(orr_inst)); | 5031 | goto DISPATCH; |
| 5492 | goto DISPATCH; | 5032 | } |
| 5493 | } | 5033 | } |
| 5494 | } | 5034 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5495 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5035 | INC_PC(sizeof(orr_inst)); |
| 5496 | INC_PC(sizeof(orr_inst)); | 5036 | FETCH_INST; |
| 5497 | FETCH_INST; | 5037 | GOTO_NEXT_INST; |
| 5498 | GOTO_NEXT_INST; | 5038 | } |
| 5499 | } | 5039 | |
| 5500 | PKHBT_INST: | 5040 | PKHBT_INST: |
| 5501 | PKHTB_INST: | 5041 | { |
| 5502 | PLD_INST: | 5042 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5503 | { | 5043 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; |
| 5504 | INC_ICOUNTER; | 5044 | RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); |
| 5505 | /* NOT IMPL */ | 5045 | } |
| 5506 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5046 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5507 | INC_PC(sizeof(stc_inst)); | 5047 | INC_PC(sizeof(pkh_inst)); |
| 5508 | FETCH_INST; | 5048 | FETCH_INST; |
| 5509 | GOTO_NEXT_INST; | 5049 | GOTO_NEXT_INST; |
| 5510 | } | 5050 | } |
| 5511 | QADD_INST: | 5051 | |
| 5512 | QADD16_INST: | 5052 | PKHTB_INST: |
| 5513 | QADD8_INST: | 5053 | { |
| 5514 | QADDSUBX_INST: | 5054 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5515 | QDADD_INST: | 5055 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; |
| 5516 | QDSUB_INST: | 5056 | int shift_imm = inst_cream->imm ? inst_cream->imm : 31; |
| 5517 | QSUB_INST: | 5057 | RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); |
| 5518 | QSUB16_INST: | 5058 | } |
| 5519 | QSUB8_INST: | 5059 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5520 | QSUBADDX_INST: | 5060 | INC_PC(sizeof(pkh_inst)); |
| 5521 | REV_INST: | 5061 | FETCH_INST; |
| 5522 | { | 5062 | GOTO_NEXT_INST; |
| 5523 | INC_ICOUNTER; | 5063 | } |
| 5524 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | 5064 | |
| 5525 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5065 | PLD_INST: |
| 5526 | RD = ((RM & 0xff) << 24) | | 5066 | { |
| 5527 | (((RM >> 8) & 0xff) << 16) | | 5067 | // Instruction not implemented |
| 5528 | (((RM >> 16) & 0xff) << 8) | | 5068 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 5529 | ((RM >> 24) & 0xff); | 5069 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5530 | if (inst_cream->Rm == 15) { | 5070 | INC_PC(sizeof(stc_inst)); |
| 5531 | DEBUG_LOG(ARM11, "in line %d\n", __LINE__); | 5071 | FETCH_INST; |
| 5532 | CITRA_IGNORE_EXIT(-1); | 5072 | GOTO_NEXT_INST; |
| 5533 | } | 5073 | } |
| 5534 | } | 5074 | |
| 5535 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5075 | QADD_INST: |
| 5536 | INC_PC(sizeof(rev_inst)); | 5076 | QADD8_INST: |
| 5537 | FETCH_INST; | 5077 | QADD16_INST: |
| 5538 | GOTO_NEXT_INST; | 5078 | QADDSUBX_INST: |
| 5539 | } | 5079 | QSUB8_INST: |
| 5540 | REV16_INST: | 5080 | QSUB16_INST: |
| 5541 | { | 5081 | QSUBADDX_INST: |
| 5542 | INC_ICOUNTER; | 5082 | { |
| 5543 | rev_inst *inst_cream = (rev_inst *)inst_base->component; | 5083 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5544 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5084 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 5545 | RD = (BITS(RM, 0, 7) << 8) | | 5085 | const u16 rm_lo = (RM & 0xFFFF); |
| 5546 | BITS(RM, 8, 15) | | 5086 | const u16 rm_hi = ((RM >> 16) & 0xFFFF); |
| 5547 | (BITS(RM, 16, 23) << 24) | | 5087 | const u16 rn_lo = (RN & 0xFFFF); |
| 5548 | (BITS(RM, 24, 31) << 16); | 5088 | const u16 rn_hi = ((RN >> 16) & 0xFFFF); |
| 5549 | } | 5089 | const u8 op2 = inst_cream->op2; |
| 5550 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5090 | |
| 5551 | INC_PC(sizeof(rev_inst)); | 5091 | u16 lo_result = 0; |
| 5552 | FETCH_INST; | 5092 | u16 hi_result = 0; |
| 5553 | GOTO_NEXT_INST; | 5093 | |
| 5554 | } | 5094 | // QADD16 |
| 5555 | REVSH_INST: | 5095 | if (op2 == 0x00) { |
| 5556 | RFE_INST: | 5096 | lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); |
| 5557 | RSB_INST: | 5097 | hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); |
| 5558 | { | 5098 | } |
| 5559 | INC_ICOUNTER; | 5099 | // QASX |
| 5560 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; | 5100 | else if (op2 == 0x01) { |
| 5561 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5101 | lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); |
| 5562 | rop = RN; | 5102 | hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); |
| 5563 | lop = SHIFTER_OPERAND; | 5103 | } |
| 5564 | if (inst_cream->Rn == 15) { | 5104 | // QSAX |
| 5565 | rop += 2 * GET_INST_SIZE(cpu);; | 5105 | else if (op2 == 0x02) { |
| 5566 | } | 5106 | lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); |
| 5567 | RD = dst = lop - rop; | 5107 | hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); |
| 5568 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5108 | } |
| 5569 | /* cpsr = spsr */ | 5109 | // QSUB16 |
| 5570 | if (CurrentModeHasSPSR) { | 5110 | else if (op2 == 0x03) { |
| 5571 | cpu->Cpsr = cpu->Spsr_copy; | 5111 | lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); |
| 5572 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5112 | hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); |
| 5573 | LOAD_NZCVT; | 5113 | } |
| 5574 | } | 5114 | // QADD8 |
| 5575 | } else if (inst_cream->S) { | 5115 | else if (op2 == 0x04) { |
| 5576 | UPDATE_NFLAG(dst); | 5116 | lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | |
| 5577 | UPDATE_ZFLAG(dst); | 5117 | ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; |
| 5578 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | 5118 | hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | |
| 5579 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 5119 | ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; |
| 5580 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | 5120 | } |
| 5581 | } | 5121 | // QSUB8 |
| 5582 | if (inst_cream->Rd == 15) { | 5122 | else if (op2 == 0x07) { |
| 5583 | INC_PC(sizeof(rsb_inst)); | 5123 | lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | |
| 5584 | goto DISPATCH; | 5124 | ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; |
| 5585 | } | 5125 | hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | |
| 5586 | } | 5126 | ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; |
| 5587 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5127 | } |
| 5588 | INC_PC(sizeof(rsb_inst)); | 5128 | |
| 5589 | FETCH_INST; | 5129 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); |
| 5590 | GOTO_NEXT_INST; | 5130 | } |
| 5591 | } | 5131 | |
| 5592 | RSC_INST: | 5132 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5593 | { | 5133 | INC_PC(sizeof(generic_arm_inst)); |
| 5594 | INC_ICOUNTER; | 5134 | FETCH_INST; |
| 5595 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; | 5135 | GOTO_NEXT_INST; |
| 5596 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5136 | } |
| 5597 | //lop = RN + !cpu->CFlag; | 5137 | |
| 5598 | //rop = SHIFTER_OPERAND; | 5138 | QDADD_INST: |
| 5599 | //RD = dst = rop - lop; | 5139 | QDSUB_INST: |
| 5600 | lop = RN; | 5140 | QSUB_INST: |
| 5601 | rop = SHIFTER_OPERAND; | 5141 | REV_INST: |
| 5602 | RD = dst = rop - lop - !cpu->CFlag; | 5142 | { |
| 5603 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5143 | rev_inst *inst_cream = (rev_inst *)inst_base->component; |
| 5604 | /* cpsr = spsr */ | 5144 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5605 | if (CurrentModeHasSPSR) { | 5145 | RD = ((RM & 0xff) << 24) | |
| 5606 | cpu->Cpsr = cpu->Spsr_copy; | 5146 | (((RM >> 8) & 0xff) << 16) | |
| 5607 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5147 | (((RM >> 16) & 0xff) << 8) | |
| 5608 | LOAD_NZCVT; | 5148 | ((RM >> 24) & 0xff); |
| 5609 | } | 5149 | if (inst_cream->Rm == 15) { |
| 5610 | } else if (inst_cream->S) { | 5150 | LOG_ERROR(Core_ARM11, "invalid operand for REV"); |
| 5611 | UPDATE_NFLAG(dst); | 5151 | CITRA_IGNORE_EXIT(-1); |
| 5612 | UPDATE_ZFLAG(dst); | 5152 | } |
| 5613 | // UPDATE_CFLAG(dst, lop, rop); | 5153 | } |
| 5614 | // UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); | 5154 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5615 | UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); | 5155 | INC_PC(sizeof(rev_inst)); |
| 5616 | // cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); | 5156 | FETCH_INST; |
| 5617 | UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); | 5157 | GOTO_NEXT_INST; |
| 5618 | } | 5158 | } |
| 5619 | if (inst_cream->Rd == 15) { | 5159 | REV16_INST: |
| 5620 | INC_PC(sizeof(rsc_inst)); | 5160 | { |
| 5621 | goto DISPATCH; | 5161 | rev_inst *inst_cream = (rev_inst *)inst_base->component; |
| 5622 | } | 5162 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5623 | } | 5163 | RD = (BITS(RM, 0, 7) << 8) | |
| 5624 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5164 | BITS(RM, 8, 15) | |
| 5625 | INC_PC(sizeof(rsc_inst)); | 5165 | (BITS(RM, 16, 23) << 24) | |
| 5626 | FETCH_INST; | 5166 | (BITS(RM, 24, 31) << 16); |
| 5627 | GOTO_NEXT_INST; | 5167 | } |
| 5628 | } | 5168 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5629 | SADD16_INST: | 5169 | INC_PC(sizeof(rev_inst)); |
| 5630 | SADD8_INST: | 5170 | FETCH_INST; |
| 5631 | SADDSUBX_INST: | 5171 | GOTO_NEXT_INST; |
| 5632 | SBC_INST: | 5172 | } |
| 5633 | { | 5173 | REVSH_INST: |
| 5634 | INC_ICOUNTER; | 5174 | RFE_INST: |
| 5635 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; | 5175 | RSB_INST: |
| 5636 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5176 | { |
| 5637 | lop = SHIFTER_OPERAND + !cpu->CFlag; | 5177 | rsb_inst *inst_cream = (rsb_inst *)inst_base->component; |
| 5638 | rop = RN; | 5178 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5639 | RD = dst = rop - lop; | 5179 | rop = RN; |
| 5640 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5180 | lop = SHIFTER_OPERAND; |
| 5641 | /* cpsr = spsr */ | 5181 | if (inst_cream->Rn == 15) { |
| 5642 | if (CurrentModeHasSPSR) { | 5182 | rop += 2 * GET_INST_SIZE(cpu);; |
| 5643 | cpu->Cpsr = cpu->Spsr_copy; | 5183 | } |
| 5644 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5184 | RD = dst = lop - rop; |
| 5645 | LOAD_NZCVT; | 5185 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5646 | } | 5186 | if (CurrentModeHasSPSR) { |
| 5647 | } else if (inst_cream->S) { | 5187 | cpu->Cpsr = cpu->Spsr_copy; |
| 5648 | UPDATE_NFLAG(dst); | 5188 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 5649 | UPDATE_ZFLAG(dst); | 5189 | LOAD_NZCVT; |
| 5650 | // UPDATE_CFLAG(dst, lop, rop); | 5190 | } |
| 5651 | //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop); | 5191 | } else if (inst_cream->S) { |
| 5652 | //rop = rop - !cpu->CFlag; | 5192 | UPDATE_NFLAG(dst); |
| 5653 | if(rop >= !cpu->CFlag) | 5193 | UPDATE_ZFLAG(dst); |
| 5654 | UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); | 5194 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); |
| 5655 | else | 5195 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); |
| 5656 | UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); | 5196 | } |
| 5657 | // cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst))); | 5197 | if (inst_cream->Rd == 15) { |
| 5658 | UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); | 5198 | INC_PC(sizeof(rsb_inst)); |
| 5659 | } | 5199 | goto DISPATCH; |
| 5660 | if (inst_cream->Rd == 15) { | 5200 | } |
| 5661 | INC_PC(sizeof(sbc_inst)); | 5201 | } |
| 5662 | goto DISPATCH; | 5202 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5663 | } | 5203 | INC_PC(sizeof(rsb_inst)); |
| 5664 | } | 5204 | FETCH_INST; |
| 5665 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5205 | GOTO_NEXT_INST; |
| 5666 | INC_PC(sizeof(sbc_inst)); | 5206 | } |
| 5667 | FETCH_INST; | 5207 | RSC_INST: |
| 5668 | GOTO_NEXT_INST; | 5208 | { |
| 5669 | } | 5209 | rsc_inst *inst_cream = (rsc_inst *)inst_base->component; |
| 5670 | SEL_INST: | 5210 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5671 | SETEND_INST: | 5211 | lop = RN; |
| 5672 | SHADD16_INST: | 5212 | rop = SHIFTER_OPERAND; |
| 5673 | SHADD8_INST: | 5213 | RD = dst = rop - lop - !cpu->CFlag; |
| 5674 | SHADDSUBX_INST: | 5214 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5675 | SHSUB16_INST: | 5215 | if (CurrentModeHasSPSR) { |
| 5676 | SHSUB8_INST: | 5216 | cpu->Cpsr = cpu->Spsr_copy; |
| 5677 | SHSUBADDX_INST: | 5217 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 5678 | SMLA_INST: | 5218 | LOAD_NZCVT; |
| 5679 | { | 5219 | } |
| 5680 | INC_ICOUNTER; | 5220 | } else if (inst_cream->S) { |
| 5681 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5221 | UPDATE_NFLAG(dst); |
| 5682 | smla_inst *inst_cream = (smla_inst *)inst_base->component; | 5222 | UPDATE_ZFLAG(dst); |
| 5683 | int32_t operand1, operand2; | 5223 | UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); |
| 5684 | if (inst_cream->x == 0) | 5224 | UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); |
| 5685 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); | 5225 | } |
| 5686 | else | 5226 | if (inst_cream->Rd == 15) { |
| 5687 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | 5227 | INC_PC(sizeof(rsc_inst)); |
| 5688 | 5228 | goto DISPATCH; | |
| 5689 | if (inst_cream->y == 0) | 5229 | } |
| 5690 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); | 5230 | } |
| 5691 | else | 5231 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5692 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | 5232 | INC_PC(sizeof(rsc_inst)); |
| 5693 | RD = operand1 * operand2 + RN; | 5233 | FETCH_INST; |
| 5694 | //FIXME: UPDATE Q FLAGS | 5234 | GOTO_NEXT_INST; |
| 5695 | } | 5235 | } |
| 5696 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5236 | |
| 5697 | INC_PC(sizeof(smla_inst)); | 5237 | SADD8_INST: |
| 5698 | FETCH_INST; | 5238 | SADD16_INST: |
| 5699 | GOTO_NEXT_INST; | 5239 | SADDSUBX_INST: |
| 5700 | } | 5240 | SSUBADDX_INST: |
| 5701 | SMLAD_INST: | 5241 | SSUB16_INST: |
| 5702 | { | 5242 | { |
| 5703 | INC_ICOUNTER; | 5243 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5704 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5244 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 5705 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | 5245 | |
| 5706 | long long int rm = cpu->Reg[inst_cream->Rm]; | 5246 | const s16 rn_lo = (RN & 0xFFFF); |
| 5707 | long long int rn = cpu->Reg[inst_cream->Rn]; | 5247 | const s16 rn_hi = ((RN >> 16) & 0xFFFF); |
| 5708 | long long int ra = cpu->Reg[inst_cream->Ra]; | 5248 | const s16 rm_lo = (RM & 0xFFFF); |
| 5709 | /* see SMUAD */ | 5249 | const s16 rm_hi = ((RM >> 16) & 0xFFFF); |
| 5710 | if(inst_cream->Ra == 15) | 5250 | |
| 5711 | CITRA_IGNORE_EXIT(-1); | 5251 | s32 lo_result = 0; |
| 5712 | int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm; | 5252 | s32 hi_result = 0; |
| 5713 | 5253 | ||
| 5714 | int half_rn, half_operand2; | 5254 | // SADD16 |
| 5715 | half_rn = rn & 0xFFFF; | 5255 | if (inst_cream->op2 == 0x00) { |
| 5716 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; | 5256 | lo_result = (rn_lo + rm_lo); |
| 5717 | 5257 | hi_result = (rn_hi + rm_hi); | |
| 5718 | half_operand2 = operand2 & 0xFFFF; | 5258 | } |
| 5719 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; | 5259 | // SASX |
| 5720 | 5260 | else if (inst_cream->op2 == 0x01) { | |
| 5721 | long long int product1 = half_rn * half_operand2; | 5261 | lo_result = (rn_lo - rm_hi); |
| 5722 | 5262 | hi_result = (rn_hi + rm_lo); | |
| 5723 | half_rn = (rn & 0xFFFF0000) >> 16; | 5263 | } |
| 5724 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; | 5264 | // SSAX |
| 5725 | 5265 | else if (inst_cream->op2 == 0x02) { | |
| 5726 | half_operand2 = (operand2 & 0xFFFF0000) >> 16; | 5266 | lo_result = (rn_lo + rm_hi); |
| 5727 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; | 5267 | hi_result = (rn_hi - rm_lo); |
| 5728 | 5268 | } | |
| 5729 | long long int product2 = half_rn * half_operand2; | 5269 | // SSUB16 |
| 5730 | 5270 | else if (inst_cream->op2 == 0x03) { | |
| 5731 | long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; | 5271 | lo_result = (rn_lo - rm_lo); |
| 5732 | long long int result = product1 + product2 + signed_ra; | 5272 | hi_result = (rn_hi - rm_hi); |
| 5733 | cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; | 5273 | } |
| 5734 | /* FIXME , should check Signed overflow */ | 5274 | |
| 5735 | } | 5275 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); |
| 5736 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5276 | |
| 5737 | INC_PC(sizeof(umlal_inst)); | 5277 | if (lo_result >= 0) { |
| 5738 | FETCH_INST; | 5278 | cpu->Cpsr |= (1 << 16); |
| 5739 | GOTO_NEXT_INST; | 5279 | cpu->Cpsr |= (1 << 17); |
| 5740 | } | 5280 | } else { |
| 5741 | 5281 | cpu->Cpsr &= ~(1 << 16); | |
| 5742 | SMLAL_INST: | 5282 | cpu->Cpsr &= ~(1 << 17); |
| 5743 | { | 5283 | } |
| 5744 | INC_ICOUNTER; | 5284 | |
| 5745 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5285 | if (hi_result >= 0) { |
| 5746 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 5286 | cpu->Cpsr |= (1 << 18); |
| 5747 | long long int rm = RM; | 5287 | cpu->Cpsr |= (1 << 19); |
| 5748 | long long int rs = RS; | 5288 | } else { |
| 5749 | if (BIT(rm, 31)) { | 5289 | cpu->Cpsr &= ~(1 << 18); |
| 5750 | rm |= 0xffffffff00000000LL; | 5290 | cpu->Cpsr &= ~(1 << 19); |
| 5751 | } | 5291 | } |
| 5752 | if (BIT(rs, 31)) { | 5292 | } |
| 5753 | rs |= 0xffffffff00000000LL; | 5293 | |
| 5754 | } | 5294 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5755 | long long int rst = rm * rs; | 5295 | INC_PC(sizeof(generic_arm_inst)); |
| 5756 | long long int rdhi32 = RDHI; | 5296 | FETCH_INST; |
| 5757 | long long int hilo = (rdhi32 << 32) + RDLO; | 5297 | GOTO_NEXT_INST; |
| 5758 | rst += hilo; | 5298 | } |
| 5759 | RDLO = BITS(rst, 0, 31); | 5299 | |
| 5760 | RDHI = BITS(rst, 32, 63); | 5300 | SBC_INST: |
| 5761 | if (inst_cream->S) { | 5301 | { |
| 5762 | cpu->NFlag = BIT(RDHI, 31); | 5302 | sbc_inst *inst_cream = (sbc_inst *)inst_base->component; |
| 5763 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 5303 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5764 | } | 5304 | lop = SHIFTER_OPERAND + !cpu->CFlag; |
| 5765 | } | 5305 | rop = RN; |
| 5766 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5306 | RD = dst = rop - lop; |
| 5767 | INC_PC(sizeof(umlal_inst)); | 5307 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5768 | FETCH_INST; | 5308 | if (CurrentModeHasSPSR) { |
| 5769 | GOTO_NEXT_INST; | 5309 | cpu->Cpsr = cpu->Spsr_copy; |
| 5770 | } | 5310 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 5771 | SMLALXY_INST: | 5311 | LOAD_NZCVT; |
| 5772 | SMLALD_INST: | 5312 | } |
| 5773 | SMLAW_INST: | 5313 | } else if (inst_cream->S) { |
| 5774 | SMLSD_INST: | 5314 | UPDATE_NFLAG(dst); |
| 5775 | SMLSLD_INST: | 5315 | UPDATE_ZFLAG(dst); |
| 5776 | SMMLA_INST: | 5316 | |
| 5777 | SMMLS_INST: | 5317 | if(rop >= !cpu->CFlag) |
| 5778 | SMMUL_INST: | 5318 | UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); |
| 5779 | SMUAD_INST: | 5319 | else |
| 5780 | SMUL_INST: | 5320 | UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); |
| 5781 | { | 5321 | |
| 5782 | INC_ICOUNTER; | 5322 | UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); |
| 5783 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5323 | } |
| 5784 | smul_inst *inst_cream = (smul_inst *)inst_base->component; | 5324 | if (inst_cream->Rd == 15) { |
| 5785 | uint32_t operand1, operand2; | 5325 | INC_PC(sizeof(sbc_inst)); |
| 5786 | if (inst_cream->x == 0) | 5326 | goto DISPATCH; |
| 5787 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); | 5327 | } |
| 5788 | else | 5328 | } |
| 5789 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | 5329 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5790 | 5330 | INC_PC(sizeof(sbc_inst)); | |
| 5791 | if (inst_cream->y == 0) | 5331 | FETCH_INST; |
| 5792 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); | 5332 | GOTO_NEXT_INST; |
| 5793 | else | 5333 | } |
| 5794 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | 5334 | |
| 5795 | RD = operand1 * operand2; | 5335 | SEL_INST: |
| 5796 | } | 5336 | { |
| 5797 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5337 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5798 | INC_PC(sizeof(smul_inst)); | 5338 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 5799 | FETCH_INST; | 5339 | |
| 5800 | GOTO_NEXT_INST; | 5340 | const u32 to = RM; |
| 5801 | } | 5341 | const u32 from = RN; |
| 5802 | SMULL_INST: | 5342 | const u32 cpsr = cpu->Cpsr; |
| 5803 | { | 5343 | |
| 5804 | INC_ICOUNTER; | 5344 | u32 result; |
| 5805 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5345 | if (cpsr & (1 << 16)) |
| 5806 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 5346 | result = from & 0xff; |
| 5807 | // DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); | 5347 | else |
| 5808 | int64_t rm = RM; | 5348 | result = to & 0xff; |
| 5809 | int64_t rs = RS; | 5349 | |
| 5810 | if (BIT(rm, 31)) { | 5350 | if (cpsr & (1 << 17)) |
| 5811 | rm |= 0xffffffff00000000LL; | 5351 | result |= from & 0x0000ff00; |
| 5812 | } | 5352 | else |
| 5813 | if (BIT(rs, 31)) { | 5353 | result |= to & 0x0000ff00; |
| 5814 | rs |= 0xffffffff00000000LL; | 5354 | |
| 5815 | } | 5355 | if (cpsr & (1 << 18)) |
| 5816 | int64_t rst = rm * rs; | 5356 | result |= from & 0x00ff0000; |
| 5817 | RDHI = BITS(rst, 32, 63); | 5357 | else |
| 5818 | RDLO = BITS(rst, 0, 31); | 5358 | result |= to & 0x00ff0000; |
| 5819 | 5359 | ||
| 5820 | 5360 | if (cpsr & (1 << 19)) | |
| 5821 | if (inst_cream->S) { | 5361 | result |= from & 0xff000000; |
| 5822 | cpu->NFlag = BIT(RDHI, 31); | 5362 | else |
| 5823 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 5363 | result |= to & 0xff000000; |
| 5824 | } | 5364 | |
| 5825 | } | 5365 | RD = result; |
| 5826 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5366 | } |
| 5827 | INC_PC(sizeof(umull_inst)); | 5367 | |
| 5828 | FETCH_INST; | 5368 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5829 | GOTO_NEXT_INST; | 5369 | INC_PC(sizeof(generic_arm_inst)); |
| 5830 | } | 5370 | FETCH_INST; |
| 5831 | SMULW_INST: | 5371 | GOTO_NEXT_INST; |
| 5832 | INC_ICOUNTER; | 5372 | } |
| 5833 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5373 | |
| 5834 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; | 5374 | SETEND_INST: |
| 5835 | // DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); | 5375 | SHADD16_INST: |
| 5836 | int64_t rm = RM; | 5376 | SHADD8_INST: |
| 5837 | int64_t rn = RN; | 5377 | SHADDSUBX_INST: |
| 5838 | if (inst_cream->m) | 5378 | SHSUB16_INST: |
| 5839 | rm = BITS(rm,16 , 31); | 5379 | SHSUB8_INST: |
| 5840 | else | 5380 | SHSUBADDX_INST: |
| 5841 | rm = BITS(rm,0 , 15); | 5381 | SMLA_INST: |
| 5842 | int64_t rst = rm * rn; | 5382 | { |
| 5843 | RD = BITS(rst, 16, 47); | 5383 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5844 | } | 5384 | smla_inst *inst_cream = (smla_inst *)inst_base->component; |
| 5845 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5385 | int32_t operand1, operand2; |
| 5846 | INC_PC(sizeof(smlad_inst)); | 5386 | if (inst_cream->x == 0) |
| 5847 | FETCH_INST; | 5387 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); |
| 5848 | GOTO_NEXT_INST; | 5388 | else |
| 5849 | 5389 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); | |
| 5850 | SMUSD_INST: | 5390 | |
| 5851 | SRS_INST: | 5391 | if (inst_cream->y == 0) |
| 5852 | SSAT_INST: | 5392 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); |
| 5853 | SSAT16_INST: | 5393 | else |
| 5854 | SSUB16_INST: | 5394 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); |
| 5855 | SSUB8_INST: | 5395 | RD = operand1 * operand2 + RN; |
| 5856 | SSUBADDX_INST: | 5396 | |
| 5857 | STC_INST: | 5397 | // TODO: FIXME: UPDATE Q FLAGS |
| 5858 | { | 5398 | } |
| 5859 | INC_ICOUNTER; | 5399 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5860 | /* NOT IMPL */ | 5400 | INC_PC(sizeof(smla_inst)); |
| 5861 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5401 | FETCH_INST; |
| 5862 | INC_PC(sizeof(stc_inst)); | 5402 | GOTO_NEXT_INST; |
| 5863 | FETCH_INST; | 5403 | } |
| 5864 | GOTO_NEXT_INST; | 5404 | SMLAD_INST: |
| 5865 | } | 5405 | { |
| 5866 | STM_INST: | 5406 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5867 | { | 5407 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 5868 | INC_ICOUNTER; | 5408 | long long int rm = cpu->Reg[inst_cream->Rm]; |
| 5869 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5409 | long long int rn = cpu->Reg[inst_cream->Rn]; |
| 5870 | unsigned int inst = inst_cream->inst; | 5410 | long long int ra = cpu->Reg[inst_cream->Ra]; |
| 5871 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5411 | |
| 5872 | int i; | 5412 | // See SMUAD |
| 5873 | unsigned int Rn = BITS(inst, 16, 19); | 5413 | if(inst_cream->Ra == 15) |
| 5874 | unsigned int old_RN = cpu->Reg[Rn]; | 5414 | CITRA_IGNORE_EXIT(-1); |
| 5875 | 5415 | int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm; | |
| 5876 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5416 | int half_rn, half_operand2; |
| 5877 | if (fault) goto MMU_EXCEPTION; | 5417 | |
| 5878 | if (BIT(inst_cream->inst, 22) == 1) { | 5418 | half_rn = rn & 0xFFFF; |
| 5879 | // DEBUG_MSG; | 5419 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; |
| 5880 | #if 1 | 5420 | |
| 5881 | for (i = 0; i < 13; i++) { | 5421 | half_operand2 = operand2 & 0xFFFF; |
| 5882 | if(BIT(inst_cream->inst, i)){ | 5422 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; |
| 5883 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5423 | |
| 5884 | if (fault) { | 5424 | long long int product1 = half_rn * half_operand2; |
| 5885 | goto MMU_EXCEPTION; | 5425 | |
| 5886 | } | 5426 | half_rn = (rn & 0xFFFF0000) >> 16; |
| 5887 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | 5427 | half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn; |
| 5888 | if (fault) goto MMU_EXCEPTION; | 5428 | |
| 5889 | addr += 4; | 5429 | half_operand2 = (operand2 & 0xFFFF0000) >> 16; |
| 5890 | phys_addr += 4; | 5430 | half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2; |
| 5891 | } | 5431 | |
| 5892 | } | 5432 | long long int product2 = half_rn * half_operand2; |
| 5893 | if (BIT(inst_cream->inst, 13)) { | 5433 | |
| 5894 | if (cpu->Mode == USER32MODE) { | 5434 | long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra; |
| 5895 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5435 | long long int result = product1 + product2 + signed_ra; |
| 5896 | if (fault) { | 5436 | cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF; |
| 5897 | goto MMU_EXCEPTION; | 5437 | |
| 5898 | } | 5438 | // TODO: FIXME should check Signed overflow |
| 5899 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | 5439 | } |
| 5900 | if (fault) goto MMU_EXCEPTION; | 5440 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5901 | addr += 4; | 5441 | INC_PC(sizeof(umlal_inst)); |
| 5902 | phys_addr += 4; | 5442 | FETCH_INST; |
| 5903 | } else { | 5443 | GOTO_NEXT_INST; |
| 5904 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); | 5444 | } |
| 5905 | if (fault) goto MMU_EXCEPTION; | 5445 | |
| 5906 | addr += 4; | 5446 | SMLAL_INST: |
| 5907 | phys_addr += 4; | 5447 | { |
| 5908 | } | 5448 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5909 | } | 5449 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 5910 | if (BIT(inst_cream->inst, 14)) { | 5450 | long long int rm = RM; |
| 5911 | if (cpu->Mode == USER32MODE) { | 5451 | long long int rs = RS; |
| 5912 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5452 | if (BIT(rm, 31)) { |
| 5913 | if (fault) { | 5453 | rm |= 0xffffffff00000000LL; |
| 5914 | goto MMU_EXCEPTION; | 5454 | } |
| 5915 | } | 5455 | if (BIT(rs, 31)) { |
| 5916 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | 5456 | rs |= 0xffffffff00000000LL; |
| 5917 | if (fault) goto MMU_EXCEPTION; | 5457 | } |
| 5918 | addr += 4; | 5458 | long long int rst = rm * rs; |
| 5919 | phys_addr += 4; | 5459 | long long int rdhi32 = RDHI; |
| 5920 | } else { | 5460 | long long int hilo = (rdhi32 << 32) + RDLO; |
| 5921 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5461 | rst += hilo; |
| 5922 | if (fault) { | 5462 | RDLO = BITS(rst, 0, 31); |
| 5923 | goto MMU_EXCEPTION; | 5463 | RDHI = BITS(rst, 32, 63); |
| 5924 | } | 5464 | if (inst_cream->S) { |
| 5925 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); | 5465 | cpu->NFlag = BIT(RDHI, 31); |
| 5926 | if (fault) goto MMU_EXCEPTION; | 5466 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 5927 | addr += 4; | 5467 | } |
| 5928 | phys_addr += 4; | 5468 | } |
| 5929 | } | 5469 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5930 | } | 5470 | INC_PC(sizeof(umlal_inst)); |
| 5931 | if (BIT(inst_cream->inst, 15)) { | 5471 | FETCH_INST; |
| 5932 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5472 | GOTO_NEXT_INST; |
| 5933 | if (fault) { | 5473 | } |
| 5934 | goto MMU_EXCEPTION; | 5474 | SMLALXY_INST: |
| 5935 | } | 5475 | SMLALD_INST: |
| 5936 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | 5476 | SMLAW_INST: |
| 5937 | if (fault) goto MMU_EXCEPTION; | 5477 | SMLSD_INST: |
| 5938 | } | 5478 | SMLSLD_INST: |
| 5939 | #endif | 5479 | SMMLA_INST: |
| 5940 | } else { | 5480 | SMMLS_INST: |
| 5941 | for( i = 0; i < 15; i ++ ){ | 5481 | SMMUL_INST: |
| 5942 | if(BIT(inst_cream->inst, i)){ | 5482 | SMUAD_INST: |
| 5943 | //arch_write_memory(cpu, bb, Addr, R(i), 32); | 5483 | SMUL_INST: |
| 5944 | //bus_write(32, addr, cpu->Reg[i]); | 5484 | { |
| 5945 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5485 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5946 | if (fault) { | 5486 | smul_inst *inst_cream = (smul_inst *)inst_base->component; |
| 5947 | goto MMU_EXCEPTION; | 5487 | uint32_t operand1, operand2; |
| 5948 | } | 5488 | if (inst_cream->x == 0) |
| 5949 | if(i == Rn) | 5489 | operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); |
| 5950 | fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); | 5490 | else |
| 5951 | else | 5491 | operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); |
| 5952 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | 5492 | |
| 5953 | if (fault) goto MMU_EXCEPTION; | 5493 | if (inst_cream->y == 0) |
| 5954 | addr += 4; | 5494 | operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); |
| 5955 | phys_addr += 4; | 5495 | else |
| 5956 | //Addr = ADD(Addr, CONST(4)); | 5496 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); |
| 5957 | } | 5497 | RD = operand1 * operand2; |
| 5958 | } | 5498 | } |
| 5959 | 5499 | cpu->Reg[15] += GET_INST_SIZE(cpu); | |
| 5960 | /* check pc reg*/ | 5500 | INC_PC(sizeof(smul_inst)); |
| 5961 | if(BIT(inst_cream->inst, i)){ | 5501 | FETCH_INST; |
| 5962 | //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32); | 5502 | GOTO_NEXT_INST; |
| 5963 | //bus_write(32, addr, cpu->Reg[i] + 8); | 5503 | } |
| 5964 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5504 | SMULL_INST: |
| 5965 | if (fault) { | 5505 | { |
| 5966 | goto MMU_EXCEPTION; | 5506 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5967 | } | 5507 | umull_inst *inst_cream = (umull_inst *)inst_base->component; |
| 5968 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | 5508 | int64_t rm = RM; |
| 5969 | if (fault) goto MMU_EXCEPTION; | 5509 | int64_t rs = RS; |
| 5970 | } | 5510 | if (BIT(rm, 31)) { |
| 5971 | } | 5511 | rm |= 0xffffffff00000000LL; |
| 5972 | } | 5512 | } |
| 5973 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5513 | if (BIT(rs, 31)) { |
| 5974 | INC_PC(sizeof(ldst_inst)); | 5514 | rs |= 0xffffffff00000000LL; |
| 5975 | FETCH_INST; | 5515 | } |
| 5976 | GOTO_NEXT_INST; | 5516 | int64_t rst = rm * rs; |
| 5977 | } | 5517 | RDHI = BITS(rst, 32, 63); |
| 5978 | SXTB_INST: | 5518 | RDLO = BITS(rst, 0, 31); |
| 5979 | { | 5519 | |
| 5980 | INC_ICOUNTER; | 5520 | if (inst_cream->S) { |
| 5981 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | 5521 | cpu->NFlag = BIT(RDHI, 31); |
| 5982 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5522 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 5983 | if (inst_cream->Rm == 15) { | 5523 | } |
| 5984 | DEBUG_LOG(ARM11, "line is %d\n", __LINE__); | 5524 | } |
| 5985 | CITRA_IGNORE_EXIT(-1); | 5525 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5986 | } | 5526 | INC_PC(sizeof(umull_inst)); |
| 5987 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); | 5527 | FETCH_INST; |
| 5988 | if (BIT(operand2, 7)) { | 5528 | GOTO_NEXT_INST; |
| 5989 | operand2 |= 0xffffff00; | 5529 | } |
| 5990 | } else | 5530 | |
| 5991 | operand2 &= 0xff; | 5531 | SMULW_INST: |
| 5992 | RD = operand2; | 5532 | { |
| 5993 | } | 5533 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5994 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5534 | smlad_inst *inst_cream = (smlad_inst *)inst_base->component; |
| 5995 | INC_PC(sizeof(sxtb_inst)); | 5535 | int64_t rm = RM; |
| 5996 | FETCH_INST; | 5536 | int64_t rn = RN; |
| 5997 | GOTO_NEXT_INST; | 5537 | if (inst_cream->m) |
| 5998 | } | 5538 | rm = BITS(rm, 16, 31); |
| 5999 | STR_INST: | 5539 | else |
| 6000 | { | 5540 | rm = BITS(rm, 0, 15); |
| 6001 | INC_ICOUNTER; | 5541 | int64_t rst = rm * rn; |
| 6002 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5542 | RD = BITS(rst, 16, 47); |
| 6003 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5543 | } |
| 6004 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5544 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6005 | if (fault) goto MMU_EXCEPTION; | 5545 | INC_PC(sizeof(smlad_inst)); |
| 6006 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5546 | FETCH_INST; |
| 6007 | //bus_write(32, addr, value); | 5547 | GOTO_NEXT_INST; |
| 6008 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5548 | } |
| 6009 | if (fault) goto MMU_EXCEPTION; | 5549 | |
| 6010 | } | 5550 | SMUSD_INST: |
| 6011 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5551 | SRS_INST: |
| 6012 | INC_PC(sizeof(ldst_inst)); | 5552 | SSAT_INST: |
| 6013 | FETCH_INST; | 5553 | { |
| 6014 | GOTO_NEXT_INST; | 5554 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 6015 | } | 5555 | ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; |
| 6016 | UXTB_INST: | 5556 | |
| 6017 | { | 5557 | u8 shift_type = inst_cream->shift_type; |
| 6018 | INC_ICOUNTER; | 5558 | u8 shift_amount = inst_cream->imm5; |
| 6019 | uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; | 5559 | u32 rn_val = RN; |
| 6020 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5560 | |
| 6021 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 5561 | // 32-bit ASR is encoded as an amount of 0. |
| 6022 | & 0xff; | 5562 | if (shift_type == 1 && shift_amount == 0) |
| 6023 | RD = operand2; | 5563 | shift_amount = 31; |
| 6024 | } | 5564 | |
| 6025 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5565 | if (shift_type == 0) |
| 6026 | INC_PC(sizeof(uxtb_inst)); | 5566 | rn_val <<= shift_amount; |
| 6027 | FETCH_INST; | 5567 | else if (shift_type == 1) |
| 6028 | GOTO_NEXT_INST; | 5568 | rn_val = ((s32)rn_val >> shift_amount); |
| 6029 | } | 5569 | |
| 6030 | UXTAB_INST: | 5570 | bool saturated = false; |
| 6031 | { | 5571 | rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated); |
| 6032 | INC_ICOUNTER; | 5572 | |
| 6033 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; | 5573 | if (saturated) |
| 6034 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5574 | cpu->Cpsr |= (1 << 27); |
| 6035 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 5575 | |
| 6036 | & 0xff; | 5576 | RD = rn_val; |
| 6037 | RD = RN + operand2; | 5577 | } |
| 6038 | } | 5578 | |
| 6039 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5579 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6040 | INC_PC(sizeof(uxtab_inst)); | 5580 | INC_PC(sizeof(ssat_inst)); |
| 6041 | FETCH_INST; | 5581 | FETCH_INST; |
| 6042 | GOTO_NEXT_INST; | 5582 | GOTO_NEXT_INST; |
| 6043 | } | 5583 | } |
| 6044 | STRB_INST: | 5584 | |
| 6045 | { | 5585 | SSAT16_INST: |
| 6046 | INC_ICOUNTER; | 5586 | SSUB8_INST: |
| 6047 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5587 | STC_INST: |
| 6048 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5588 | { |
| 6049 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5589 | // Instruction not implemented |
| 6050 | if (fault) goto MMU_EXCEPTION; | 5590 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 6051 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | 5591 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6052 | //bus_write(8, addr, value); | 5592 | INC_PC(sizeof(stc_inst)); |
| 6053 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5593 | FETCH_INST; |
| 6054 | if (fault) goto MMU_EXCEPTION; | 5594 | GOTO_NEXT_INST; |
| 6055 | } | 5595 | } |
| 6056 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5596 | STM_INST: |
| 6057 | INC_PC(sizeof(ldst_inst)); | 5597 | { |
| 6058 | FETCH_INST; | 5598 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6059 | GOTO_NEXT_INST; | 5599 | unsigned int inst = inst_cream->inst; |
| 6060 | } | 5600 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6061 | STRBT_INST: | 5601 | int i; |
| 6062 | { | 5602 | unsigned int Rn = BITS(inst, 16, 19); |
| 6063 | INC_ICOUNTER; | 5603 | unsigned int old_RN = cpu->Reg[Rn]; |
| 6064 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5604 | |
| 6065 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5605 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 6066 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5606 | if (fault) goto MMU_EXCEPTION; |
| 6067 | if (fault) goto MMU_EXCEPTION; | 5607 | if (BIT(inst_cream->inst, 22) == 1) { |
| 6068 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | 5608 | for (i = 0; i < 13; i++) { |
| 6069 | //bus_write(8, addr, value); | 5609 | if(BIT(inst_cream->inst, i)){ |
| 6070 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5610 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 6071 | if (fault) goto MMU_EXCEPTION; | 5611 | if (fault) goto MMU_EXCEPTION; |
| 6072 | } | 5612 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); |
| 6073 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5613 | if (fault) goto MMU_EXCEPTION; |
| 6074 | //if (BITS(inst_cream->inst, 12, 15) == 15) | 5614 | addr += 4; |
| 6075 | // goto DISPATCH; | 5615 | phys_addr += 4; |
| 6076 | INC_PC(sizeof(ldst_inst)); | 5616 | } |
| 6077 | FETCH_INST; | 5617 | } |
| 6078 | GOTO_NEXT_INST; | 5618 | if (BIT(inst_cream->inst, 13)) { |
| 6079 | } | 5619 | if (cpu->Mode == USER32MODE) { |
| 6080 | STRD_INST: | 5620 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 6081 | { | 5621 | if (fault) goto MMU_EXCEPTION; |
| 6082 | INC_ICOUNTER; | 5622 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); |
| 6083 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5623 | if (fault) goto MMU_EXCEPTION; |
| 6084 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5624 | addr += 4; |
| 6085 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5625 | phys_addr += 4; |
| 6086 | if (fault) goto MMU_EXCEPTION; | 5626 | } else { |
| 6087 | uint32_t rear_phys_addr; | 5627 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); |
| 6088 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); | 5628 | if (fault) goto MMU_EXCEPTION; |
| 5629 | addr += 4; | ||
| 5630 | phys_addr += 4; | ||
| 5631 | } | ||
| 5632 | } | ||
| 5633 | if (BIT(inst_cream->inst, 14)) { | ||
| 5634 | if (cpu->Mode == USER32MODE) { | ||
| 5635 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5636 | if (fault) goto MMU_EXCEPTION; | ||
| 5637 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 5638 | if (fault) goto MMU_EXCEPTION; | ||
| 5639 | addr += 4; | ||
| 5640 | phys_addr += 4; | ||
| 5641 | } else { | ||
| 5642 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5643 | if (fault) goto MMU_EXCEPTION; | ||
| 5644 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); | ||
| 5645 | if (fault) goto MMU_EXCEPTION; | ||
| 5646 | addr += 4; | ||
| 5647 | phys_addr += 4; | ||
| 5648 | } | ||
| 5649 | } | ||
| 5650 | if (BIT(inst_cream->inst, 15)) { | ||
| 5651 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5652 | if (fault) goto MMU_EXCEPTION; | ||
| 5653 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | ||
| 5654 | if (fault) goto MMU_EXCEPTION; | ||
| 5655 | } | ||
| 5656 | } else { | ||
| 5657 | for( i = 0; i < 15; i ++ ) { | ||
| 5658 | if(BIT(inst_cream->inst, i)) { | ||
| 5659 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5660 | if (fault) goto MMU_EXCEPTION; | ||
| 5661 | if(i == Rn) | ||
| 5662 | fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); | ||
| 5663 | else | ||
| 5664 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 5665 | if (fault) goto MMU_EXCEPTION; | ||
| 5666 | addr += 4; | ||
| 5667 | phys_addr += 4; | ||
| 5668 | } | ||
| 5669 | } | ||
| 5670 | |||
| 5671 | // Check PC reg | ||
| 5672 | if(BIT(inst_cream->inst, i)) { | ||
| 5673 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5674 | if (fault) goto MMU_EXCEPTION; | ||
| 5675 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | ||
| 5676 | if (fault) goto MMU_EXCEPTION; | ||
| 5677 | } | ||
| 5678 | } | ||
| 5679 | } | ||
| 5680 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5681 | INC_PC(sizeof(ldst_inst)); | ||
| 5682 | FETCH_INST; | ||
| 5683 | GOTO_NEXT_INST; | ||
| 5684 | } | ||
| 5685 | SXTB_INST: | ||
| 5686 | { | ||
| 5687 | sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; | ||
| 5688 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5689 | if (inst_cream->Rm == 15) { | ||
| 5690 | LOG_ERROR(Core_ARM11, "invalid operand for SXTB"); | ||
| 5691 | CITRA_IGNORE_EXIT(-1); | ||
| 5692 | } | ||
| 5693 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); | ||
| 5694 | if (BIT(operand2, 7)) { | ||
| 5695 | operand2 |= 0xffffff00; | ||
| 5696 | } else | ||
| 5697 | operand2 &= 0xff; | ||
| 5698 | RD = operand2; | ||
| 5699 | } | ||
| 5700 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5701 | INC_PC(sizeof(sxtb_inst)); | ||
| 5702 | FETCH_INST; | ||
| 5703 | GOTO_NEXT_INST; | ||
| 5704 | } | ||
| 5705 | STR_INST: | ||
| 5706 | { | ||
| 5707 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 5708 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5709 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 5710 | if (fault) goto MMU_EXCEPTION; | ||
| 5711 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | ||
| 5712 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | ||
| 5713 | if (fault) goto MMU_EXCEPTION; | ||
| 5714 | } | ||
| 5715 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5716 | INC_PC(sizeof(ldst_inst)); | ||
| 5717 | FETCH_INST; | ||
| 5718 | GOTO_NEXT_INST; | ||
| 5719 | } | ||
| 5720 | UXTB_INST: | ||
| 5721 | { | ||
| 5722 | uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; | ||
| 5723 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5724 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | ||
| 5725 | & 0xff; | ||
| 5726 | RD = operand2; | ||
| 5727 | } | ||
| 5728 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5729 | INC_PC(sizeof(uxtb_inst)); | ||
| 5730 | FETCH_INST; | ||
| 5731 | GOTO_NEXT_INST; | ||
| 5732 | } | ||
| 5733 | UXTAB_INST: | ||
| 5734 | { | ||
| 5735 | uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; | ||
| 5736 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5737 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | ||
| 5738 | & 0xff; | ||
| 5739 | RD = RN + operand2; | ||
| 5740 | } | ||
| 5741 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5742 | INC_PC(sizeof(uxtab_inst)); | ||
| 5743 | FETCH_INST; | ||
| 5744 | GOTO_NEXT_INST; | ||
| 5745 | } | ||
| 5746 | STRB_INST: | ||
| 5747 | { | ||
| 5748 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 5749 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5750 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 5751 | if (fault) goto MMU_EXCEPTION; | ||
| 5752 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | ||
| 5753 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | ||
| 5754 | if (fault) goto MMU_EXCEPTION; | ||
| 5755 | } | ||
| 5756 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5757 | INC_PC(sizeof(ldst_inst)); | ||
| 5758 | FETCH_INST; | ||
| 5759 | GOTO_NEXT_INST; | ||
| 5760 | } | ||
| 5761 | STRBT_INST: | ||
| 5762 | { | ||
| 5763 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 5764 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5765 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 5766 | if (fault) goto MMU_EXCEPTION; | ||
| 5767 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | ||
| 5768 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | ||
| 5769 | if (fault) goto MMU_EXCEPTION; | ||
| 5770 | } | ||
| 5771 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5772 | INC_PC(sizeof(ldst_inst)); | ||
| 5773 | FETCH_INST; | ||
| 5774 | GOTO_NEXT_INST; | ||
| 5775 | } | ||
| 5776 | STRD_INST: | ||
| 5777 | { | ||
| 5778 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | ||
| 5779 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5780 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | ||
| 5781 | if (fault) goto MMU_EXCEPTION; | ||
| 5782 | uint32_t rear_phys_addr; | ||
| 5783 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); | ||
| 6089 | if (fault){ | 5784 | if (fault){ |
| 6090 | ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n"); | 5785 | LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr"); |
| 6091 | CITRA_IGNORE_EXIT(-1); | 5786 | CITRA_IGNORE_EXIT(-1); |
| 6092 | goto MMU_EXCEPTION; | 5787 | goto MMU_EXCEPTION; |
| 6093 | } | 5788 | } |
| 6094 | 5789 | ||
| 6095 | //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0); | 5790 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6096 | //if (fault) goto MMU_EXCEPTION; | 5791 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 6097 | 5792 | if (fault) goto MMU_EXCEPTION; | |
| 6098 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5793 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; |
| 6099 | //bus_write(32, addr, value); | 5794 | fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); |
| 6100 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5795 | if (fault) goto MMU_EXCEPTION; |
| 6101 | if (fault) goto MMU_EXCEPTION; | 5796 | } |
| 6102 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; | 5797 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6103 | //bus_write(32, addr, value); | 5798 | INC_PC(sizeof(ldst_inst)); |
| 6104 | fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); | 5799 | FETCH_INST; |
| 6105 | if (fault) goto MMU_EXCEPTION; | 5800 | GOTO_NEXT_INST; |
| 6106 | } | 5801 | } |
| 6107 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5802 | STREX_INST: |
| 6108 | INC_PC(sizeof(ldst_inst)); | 5803 | { |
| 6109 | FETCH_INST; | 5804 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6110 | GOTO_NEXT_INST; | 5805 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6111 | } | 5806 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 6112 | STREX_INST: | 5807 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; |
| 6113 | { | 5808 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 6114 | INC_ICOUNTER; | 5809 | if (fault) goto MMU_EXCEPTION; |
| 6115 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5810 | |
| 6116 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5811 | int dest_reg = BITS(inst_cream->inst, 12, 15); |
| 6117 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5812 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ |
| 6118 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; | 5813 | remove_exclusive(cpu, phys_addr); |
| 6119 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5814 | cpu->Reg[dest_reg] = 0; |
| 6120 | if (fault) goto MMU_EXCEPTION; | 5815 | cpu->exclusive_state = 0; |
| 6121 | 5816 | ||
| 6122 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5817 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 6123 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ | 5818 | if (fault) goto MMU_EXCEPTION; |
| 6124 | remove_exclusive(cpu, phys_addr); | 5819 | } else { |
| 6125 | cpu->Reg[dest_reg] = 0; | 5820 | // Failed to write due to mutex access |
| 6126 | cpu->exclusive_state = 0; | 5821 | cpu->Reg[dest_reg] = 1; |
| 6127 | 5822 | } | |
| 6128 | // bus_write(32, addr, value); | 5823 | } |
| 6129 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5824 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6130 | if (fault) goto MMU_EXCEPTION; | 5825 | INC_PC(sizeof(ldst_inst)); |
| 6131 | } | 5826 | FETCH_INST; |
| 6132 | else{ | 5827 | GOTO_NEXT_INST; |
| 6133 | /* Failed to write due to mutex access */ | 5828 | } |
| 6134 | cpu->Reg[dest_reg] = 1; | 5829 | STREXB_INST: |
| 6135 | } | 5830 | { |
| 6136 | } | 5831 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6137 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5832 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6138 | INC_PC(sizeof(ldst_inst)); | 5833 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 6139 | FETCH_INST; | 5834 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; |
| 6140 | GOTO_NEXT_INST; | 5835 | fault = check_address_validity(cpu, addr, &phys_addr, 0); |
| 6141 | } | 5836 | if (fault) goto MMU_EXCEPTION; |
| 6142 | STREXB_INST: | 5837 | int dest_reg = BITS(inst_cream->inst, 12, 15); |
| 6143 | { | 5838 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ |
| 6144 | INC_ICOUNTER; | 5839 | remove_exclusive(cpu, phys_addr); |
| 6145 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5840 | cpu->Reg[dest_reg] = 0; |
| 6146 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5841 | cpu->exclusive_state = 0; |
| 6147 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5842 | fault = interpreter_write_memory(addr, phys_addr, value, 8); |
| 6148 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; | 5843 | if (fault) goto MMU_EXCEPTION; |
| 6149 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5844 | } else { |
| 6150 | if (fault) goto MMU_EXCEPTION; | 5845 | cpu->Reg[dest_reg] = 1; |
| 6151 | //bus_write(8, addr, value); | 5846 | } |
| 6152 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5847 | } |
| 6153 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ | 5848 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6154 | remove_exclusive(cpu, phys_addr); | 5849 | INC_PC(sizeof(ldst_inst)); |
| 6155 | cpu->Reg[dest_reg] = 0; | 5850 | FETCH_INST; |
| 6156 | cpu->exclusive_state = 0; | 5851 | GOTO_NEXT_INST; |
| 6157 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5852 | } |
| 6158 | if (fault) goto MMU_EXCEPTION; | 5853 | STRH_INST: |
| 6159 | 5854 | { | |
| 6160 | } | 5855 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6161 | else{ | 5856 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6162 | cpu->Reg[dest_reg] = 1; | 5857 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 6163 | } | 5858 | if (fault) goto MMU_EXCEPTION; |
| 6164 | } | 5859 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; |
| 6165 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5860 | fault = interpreter_write_memory(addr, phys_addr, value, 16); |
| 6166 | INC_PC(sizeof(ldst_inst)); | 5861 | if (fault) goto MMU_EXCEPTION; |
| 6167 | FETCH_INST; | 5862 | } |
| 6168 | GOTO_NEXT_INST; | 5863 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6169 | } | 5864 | INC_PC(sizeof(ldst_inst)); |
| 6170 | STRH_INST: | 5865 | FETCH_INST; |
| 6171 | { | 5866 | GOTO_NEXT_INST; |
| 6172 | INC_ICOUNTER; | 5867 | } |
| 6173 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5868 | STRT_INST: |
| 6174 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5869 | { |
| 6175 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5870 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 6176 | if (fault) goto MMU_EXCEPTION; | 5871 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6177 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; | 5872 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); |
| 6178 | //bus_write(16, addr, value); | 5873 | if (fault) goto MMU_EXCEPTION; |
| 6179 | fault = interpreter_write_memory(addr, phys_addr, value, 16); | 5874 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6180 | if (fault) goto MMU_EXCEPTION; | 5875 | fault = interpreter_write_memory(addr, phys_addr, value, 32); |
| 6181 | } | 5876 | if (fault) goto MMU_EXCEPTION; |
| 6182 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5877 | } |
| 6183 | //if (BITS(inst_cream->inst, 12, 15) == 15) | 5878 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6184 | // goto DISPATCH; | 5879 | INC_PC(sizeof(ldst_inst)); |
| 6185 | INC_PC(sizeof(ldst_inst)); | 5880 | FETCH_INST; |
| 6186 | FETCH_INST; | 5881 | GOTO_NEXT_INST; |
| 6187 | GOTO_NEXT_INST; | 5882 | } |
| 6188 | } | 5883 | SUB_INST: |
| 6189 | STRT_INST: | 5884 | { |
| 6190 | { | 5885 | sub_inst *inst_cream = (sub_inst *)inst_base->component; |
| 6191 | INC_ICOUNTER; | 5886 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6192 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5887 | lop = RN; |
| 6193 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5888 | if (inst_cream->Rn == 15) { |
| 6194 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5889 | lop += 8; |
| 6195 | if (fault) goto MMU_EXCEPTION; | 5890 | } |
| 6196 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5891 | rop = SHIFTER_OPERAND; |
| 6197 | //bus_write(16, addr, value); | 5892 | RD = dst = lop - rop; |
| 6198 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5893 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 6199 | if (fault) goto MMU_EXCEPTION; | 5894 | if (CurrentModeHasSPSR) { |
| 6200 | } | 5895 | cpu->Cpsr = cpu->Spsr_copy; |
| 6201 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5896 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); |
| 6202 | INC_PC(sizeof(ldst_inst)); | 5897 | LOAD_NZCVT; |
| 6203 | FETCH_INST; | 5898 | } |
| 6204 | GOTO_NEXT_INST; | 5899 | } else if (inst_cream->S) { |
| 6205 | } | 5900 | UPDATE_NFLAG(dst); |
| 6206 | SUB_INST: | 5901 | UPDATE_ZFLAG(dst); |
| 6207 | { | 5902 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); |
| 6208 | INC_ICOUNTER; | 5903 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); |
| 6209 | sub_inst *inst_cream = (sub_inst *)inst_base->component; | 5904 | } |
| 6210 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5905 | if (inst_cream->Rd == 15) { |
| 6211 | lop = RN; | 5906 | INC_PC(sizeof(sub_inst)); |
| 6212 | if (inst_cream->Rn == 15) { | 5907 | goto DISPATCH; |
| 6213 | lop += 8; | 5908 | } |
| 6214 | } | 5909 | } |
| 6215 | rop = SHIFTER_OPERAND; | 5910 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6216 | RD = dst = lop - rop; | 5911 | INC_PC(sizeof(sub_inst)); |
| 6217 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5912 | FETCH_INST; |
| 6218 | /* cpsr = spsr */ | 5913 | GOTO_NEXT_INST; |
| 6219 | if (CurrentModeHasSPSR) { | 5914 | } |
| 6220 | cpu->Cpsr = cpu->Spsr_copy; | 5915 | SWI_INST: |
| 6221 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5916 | { |
| 6222 | LOAD_NZCVT; | 5917 | swi_inst *inst_cream = (swi_inst *)inst_base->component; |
| 6223 | } | 5918 | |
| 6224 | } else if (inst_cream->S) { | 5919 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) |
| 6225 | UPDATE_NFLAG(dst); | 5920 | HLE::CallSVC(Memory::Read32(cpu->Reg[15])); |
| 6226 | UPDATE_ZFLAG(dst); | 5921 | |
| 6227 | // UPDATE_CFLAG(dst, lop, rop); | 5922 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6228 | UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | 5923 | INC_PC(sizeof(swi_inst)); |
| 6229 | // UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | 5924 | FETCH_INST; |
| 6230 | UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | 5925 | GOTO_NEXT_INST; |
| 6231 | } | 5926 | } |
| 6232 | if (inst_cream->Rd == 15) { | 5927 | SWP_INST: |
| 6233 | INC_PC(sizeof(sub_inst)); | 5928 | { |
| 6234 | goto DISPATCH; | 5929 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 6235 | } | 5930 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6236 | } | 5931 | addr = RN; |
| 6237 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5932 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 6238 | INC_PC(sizeof(sub_inst)); | 5933 | if (fault) goto MMU_EXCEPTION; |
| 6239 | FETCH_INST; | 5934 | unsigned int value; |
| 6240 | GOTO_NEXT_INST; | 5935 | fault = interpreter_read_memory(addr, phys_addr, value, 32); |
| 6241 | } | 5936 | if (fault) goto MMU_EXCEPTION; |
| 6242 | SWI_INST: | 5937 | fault = interpreter_write_memory(addr, phys_addr, RM, 32); |
| 6243 | { | 5938 | if (fault) goto MMU_EXCEPTION; |
| 6244 | INC_ICOUNTER; | 5939 | |
| 6245 | swi_inst *inst_cream = (swi_inst *)inst_base->component; | 5940 | assert((phys_addr & 0x3) == 0); |
| 6246 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5941 | RD = value; |
| 6247 | if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode | 5942 | } |
| 6248 | //arm_dyncom_SWI(cpu, inst_cream->num); | 5943 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6249 | HLE::CallSVC(Memory::Read32(cpu->Reg[15])); | 5944 | INC_PC(sizeof(swp_inst)); |
| 6250 | } else { | 5945 | FETCH_INST; |
| 6251 | cpu->syscallSig = 1; | 5946 | GOTO_NEXT_INST; |
| 6252 | goto END; | 5947 | } |
| 6253 | } | 5948 | SWPB_INST: |
| 6254 | } | 5949 | { |
| 6255 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5950 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 6256 | INC_PC(sizeof(swi_inst)); | 5951 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6257 | FETCH_INST; | 5952 | addr = RN; |
| 6258 | GOTO_NEXT_INST; | 5953 | fault = check_address_validity(cpu, addr, &phys_addr, 1); |
| 6259 | } | 5954 | if (fault) goto MMU_EXCEPTION; |
| 6260 | SWP_INST: | 5955 | unsigned int value; |
| 6261 | { | 5956 | fault = interpreter_read_memory(addr, phys_addr, value, 8); |
| 6262 | INC_ICOUNTER; | 5957 | if (fault) goto MMU_EXCEPTION; |
| 6263 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 5958 | fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); |
| 6264 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5959 | if (fault) goto MMU_EXCEPTION; |
| 6265 | addr = RN; | 5960 | } |
| 6266 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5961 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6267 | if (fault) goto MMU_EXCEPTION; | 5962 | INC_PC(sizeof(swp_inst)); |
| 6268 | unsigned int value; | 5963 | FETCH_INST; |
| 6269 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 5964 | GOTO_NEXT_INST; |
| 6270 | if (fault) goto MMU_EXCEPTION; | 5965 | } |
| 6271 | fault = interpreter_write_memory(addr, phys_addr, RM, 32); | 5966 | SXTAB_INST: |
| 6272 | if (fault) goto MMU_EXCEPTION; | 5967 | { |
| 6273 | 5968 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; | |
| 6274 | /* ROR(data, 8*UInt(address<1:0>)); */ | 5969 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6275 | assert((phys_addr & 0x3) == 0); | 5970 | // R15 should be check |
| 6276 | RD = value; | 5971 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ |
| 6277 | } | 5972 | CITRA_IGNORE_EXIT(-1); |
| 6278 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5973 | } |
| 6279 | INC_PC(sizeof(swp_inst)); | 5974 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; |
| 6280 | FETCH_INST; | 5975 | |
| 6281 | GOTO_NEXT_INST; | 5976 | // Sign extend for byte |
| 6282 | } | 5977 | operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; |
| 6283 | SWPB_INST: | 5978 | RD = RN + operand2; |
| 6284 | { | 5979 | } |
| 6285 | INC_ICOUNTER; | 5980 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6286 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 5981 | INC_PC(sizeof(uxtab_inst)); |
| 6287 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5982 | FETCH_INST; |
| 6288 | addr = RN; | 5983 | GOTO_NEXT_INST; |
| 6289 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5984 | } |
| 6290 | if (fault) goto MMU_EXCEPTION; | 5985 | SXTAB16_INST: |
| 6291 | unsigned int value; | 5986 | SXTAH_INST: |
| 6292 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | 5987 | { |
| 6293 | if (fault) goto MMU_EXCEPTION; | 5988 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; |
| 6294 | fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); | 5989 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6295 | if (fault) goto MMU_EXCEPTION; | 5990 | // R15 should be check |
| 6296 | 5991 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15) { | |
| 6297 | /* FIXME */ | 5992 | CITRA_IGNORE_EXIT(-1); |
| 6298 | #if 0 | 5993 | } |
| 6299 | if Shared(address) then | 5994 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; |
| 6300 | /* ARMv6 */ | 5995 | // Sign extend for half |
| 6301 | physical_address = TLB(address) | 5996 | operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; |
| 6302 | ClearExclusiveByAddress(physical_address,processor_id,1) | 5997 | RD = RN + operand2; |
| 6303 | /* See Summary of operation on page A2-49 */ | 5998 | } |
| 6304 | #endif | 5999 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6305 | } | 6000 | INC_PC(sizeof(sxtah_inst)); |
| 6306 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6001 | FETCH_INST; |
| 6307 | INC_PC(sizeof(swp_inst)); | 6002 | GOTO_NEXT_INST; |
| 6308 | FETCH_INST; | 6003 | } |
| 6309 | GOTO_NEXT_INST; | 6004 | SXTB16_INST: |
| 6310 | } | 6005 | TEQ_INST: |
| 6311 | SXTAB_INST: | 6006 | { |
| 6312 | { | 6007 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6313 | INC_ICOUNTER; | 6008 | teq_inst *inst_cream = (teq_inst *)inst_base->component; |
| 6314 | sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; | 6009 | lop = RN; |
| 6315 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6010 | |
| 6316 | /* R15 should be check */ | 6011 | if (inst_cream->Rn == 15) |
| 6317 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ | 6012 | lop += GET_INST_SIZE(cpu) * 2; |
| 6318 | CITRA_IGNORE_EXIT(-1); | 6013 | |
| 6319 | } | 6014 | rop = SHIFTER_OPERAND; |
| 6320 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) | 6015 | dst = lop ^ rop; |
| 6321 | & 0xff; | 6016 | |
| 6322 | /* sign extend for byte */ | 6017 | UPDATE_NFLAG(dst); |
| 6323 | operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; | 6018 | UPDATE_ZFLAG(dst); |
| 6324 | RD = RN + operand2; | 6019 | UPDATE_CFLAG_WITH_SC; |
| 6325 | } | 6020 | } |
| 6326 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6021 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6327 | INC_PC(sizeof(uxtab_inst)); | 6022 | INC_PC(sizeof(teq_inst)); |
| 6328 | FETCH_INST; | 6023 | FETCH_INST; |
| 6329 | GOTO_NEXT_INST; | 6024 | GOTO_NEXT_INST; |
| 6330 | } | 6025 | } |
| 6331 | SXTAB16_INST: | 6026 | TST_INST: |
| 6332 | SXTAH_INST: | 6027 | { |
| 6333 | { | 6028 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6334 | INC_ICOUNTER; | 6029 | tst_inst *inst_cream = (tst_inst *)inst_base->component; |
| 6335 | sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; | 6030 | lop = RN; |
| 6336 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6031 | |
| 6337 | /* R15 should be check */ | 6032 | if (inst_cream->Rn == 15) |
| 6338 | if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ | 6033 | lop += GET_INST_SIZE(cpu) * 2; |
| 6339 | CITRA_IGNORE_EXIT(-1); | 6034 | |
| 6340 | } | 6035 | rop = SHIFTER_OPERAND; |
| 6341 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; | 6036 | dst = lop & rop; |
| 6342 | /* sign extend for half */ | 6037 | |
| 6343 | operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2; | 6038 | UPDATE_NFLAG(dst); |
| 6344 | RD = RN + operand2; | 6039 | UPDATE_ZFLAG(dst); |
| 6345 | } | 6040 | UPDATE_CFLAG_WITH_SC; |
| 6346 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6041 | } |
| 6347 | INC_PC(sizeof(sxtah_inst)); | 6042 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6348 | FETCH_INST; | 6043 | INC_PC(sizeof(tst_inst)); |
| 6349 | GOTO_NEXT_INST; | 6044 | FETCH_INST; |
| 6350 | } | 6045 | GOTO_NEXT_INST; |
| 6351 | SXTB16_INST: | 6046 | } |
| 6352 | TEQ_INST: | 6047 | UADD8_INST: |
| 6353 | { | 6048 | UADD16_INST: |
| 6354 | INC_ICOUNTER; | 6049 | UADDSUBX_INST: |
| 6355 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6050 | |
| 6356 | teq_inst *inst_cream = (teq_inst *)inst_base->component; | 6051 | UHADD8_INST: |
| 6357 | lop = RN; | 6052 | UHADD16_INST: |
| 6358 | if (inst_cream->Rn == 15) | 6053 | UHADDSUBX_INST: |
| 6359 | lop += GET_INST_SIZE(cpu) * 2; | 6054 | UHSUBADDX_INST: |
| 6360 | 6055 | UHSUB8_INST: | |
| 6361 | rop = SHIFTER_OPERAND; | 6056 | UHSUB16_INST: |
| 6362 | dst = lop ^ rop; | 6057 | { |
| 6363 | 6058 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | |
| 6364 | UPDATE_NFLAG(dst); | 6059 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 6365 | UPDATE_ZFLAG(dst); | 6060 | const u32 rm_val = RM; |
| 6366 | UPDATE_CFLAG_WITH_SC; | 6061 | const u32 rn_val = RN; |
| 6367 | } | 6062 | const u8 op2 = inst_cream->op2; |
| 6368 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6063 | |
| 6369 | INC_PC(sizeof(teq_inst)); | 6064 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) |
| 6370 | FETCH_INST; | 6065 | { |
| 6371 | GOTO_NEXT_INST; | 6066 | u32 lo_val = 0; |
| 6372 | } | 6067 | u32 hi_val = 0; |
| 6373 | TST_INST: | 6068 | |
| 6374 | { | 6069 | // UHADD16 |
| 6375 | INC_ICOUNTER; | 6070 | if (op2 == 0x00) { |
| 6376 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6071 | lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); |
| 6377 | tst_inst *inst_cream = (tst_inst *)inst_base->component; | 6072 | hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); |
| 6378 | lop = RN; | 6073 | } |
| 6379 | if (inst_cream->Rn == 15) | 6074 | // UHASX |
| 6380 | lop += GET_INST_SIZE(cpu) * 2; | 6075 | else if (op2 == 0x01) { |
| 6381 | rop = SHIFTER_OPERAND; | 6076 | lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); |
| 6382 | dst = lop & rop; | 6077 | hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); |
| 6383 | 6078 | } | |
| 6384 | UPDATE_NFLAG(dst); | 6079 | // UHSAX |
| 6385 | UPDATE_ZFLAG(dst); | 6080 | else if (op2 == 0x02) { |
| 6386 | UPDATE_CFLAG_WITH_SC; | 6081 | lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); |
| 6387 | } | 6082 | hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); |
| 6388 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6083 | } |
| 6389 | INC_PC(sizeof(tst_inst)); | 6084 | // UHSUB16 |
| 6390 | FETCH_INST; | 6085 | else if (op2 == 0x03) { |
| 6391 | GOTO_NEXT_INST; | 6086 | lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); |
| 6392 | } | 6087 | hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); |
| 6393 | UADD16_INST: | 6088 | } |
| 6394 | UADD8_INST: | 6089 | |
| 6395 | UADDSUBX_INST: | 6090 | lo_val >>= 1; |
| 6396 | UHADD16_INST: | 6091 | hi_val >>= 1; |
| 6397 | UHADD8_INST: | 6092 | |
| 6398 | UHADDSUBX_INST: | 6093 | RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); |
| 6399 | UHSUB16_INST: | 6094 | } |
| 6400 | UHSUB8_INST: | 6095 | else if (op2 == 0x04 || op2 == 0x07) { |
| 6401 | UHSUBADDX_INST: | 6096 | u32 sum1; |
| 6402 | UMAAL_INST: | 6097 | u32 sum2; |
| 6403 | UMLAL_INST: | 6098 | u32 sum3; |
| 6404 | { | 6099 | u32 sum4; |
| 6405 | INC_ICOUNTER; | 6100 | |
| 6406 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6101 | // UHADD8 |
| 6407 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; | 6102 | if (op2 == 0x04) { |
| 6408 | unsigned long long int rm = RM; | 6103 | sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); |
| 6409 | unsigned long long int rs = RS; | 6104 | sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); |
| 6410 | unsigned long long int rst = rm * rs; | 6105 | sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); |
| 6411 | unsigned long long int add = ((unsigned long long) RDHI)<<32; | 6106 | sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); |
| 6412 | add += RDLO; | 6107 | } |
| 6413 | //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add); | 6108 | // UHSUB8 |
| 6414 | rst += add; | 6109 | else { |
| 6415 | RDLO = BITS(rst, 0, 31); | 6110 | sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); |
| 6416 | RDHI = BITS(rst, 32, 63); | 6111 | sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); |
| 6417 | 6112 | sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | |
| 6418 | if (inst_cream->S) | 6113 | sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); |
| 6419 | { | 6114 | } |
| 6420 | cpu->NFlag = BIT(RDHI, 31); | 6115 | |
| 6421 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 6116 | sum1 >>= 1; |
| 6422 | } | 6117 | sum2 >>= 1; |
| 6423 | } | 6118 | sum3 >>= 1; |
| 6424 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6119 | sum4 >>= 1; |
| 6425 | INC_PC(sizeof(umlal_inst)); | 6120 | |
| 6426 | FETCH_INST; | 6121 | RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); |
| 6427 | GOTO_NEXT_INST; | 6122 | } |
| 6428 | } | 6123 | } |
| 6429 | UMULL_INST: | 6124 | |
| 6430 | { | 6125 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6431 | INC_ICOUNTER; | 6126 | INC_PC(sizeof(generic_arm_inst)); |
| 6432 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 6127 | FETCH_INST; |
| 6433 | umull_inst *inst_cream = (umull_inst *)inst_base->component; | 6128 | GOTO_NEXT_INST; |
| 6434 | unsigned long long int rm = RM; | 6129 | } |
| 6435 | unsigned long long int rs = RS; | 6130 | |
| 6436 | unsigned long long int rst = rm * rs; | 6131 | UMAAL_INST: |
| 6437 | // DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst); | 6132 | { |
| 6438 | RDHI = BITS(rst, 32, 63); | 6133 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 6439 | RDLO = BITS(rst, 0, 31); | 6134 | umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; |
| 6440 | 6135 | const u32 rm = RM; | |
| 6441 | if (inst_cream->S) { | 6136 | const u32 rn = RN; |
| 6442 | cpu->NFlag = BIT(RDHI, 31); | 6137 | const u32 rd_lo = RDLO; |
| 6443 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 6138 | const u32 rd_hi = RDHI; |
| 6444 | } | 6139 | const u64 result = (rm * rn) + rd_lo + rd_hi; |
| 6445 | } | 6140 | |
| 6446 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6141 | RDLO = (result & 0xFFFFFFFF); |
| 6447 | INC_PC(sizeof(umull_inst)); | 6142 | RDHI = ((result >> 32) & 0xFFFFFFFF); |
| 6448 | FETCH_INST; | 6143 | } |
| 6449 | GOTO_NEXT_INST; | 6144 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6450 | } | 6145 | INC_PC(sizeof(umaal_inst)); |
| 6451 | B_2_THUMB: | 6146 | FETCH_INST; |
| 6452 | { | 6147 | GOTO_NEXT_INST; |
| 6453 | INC_ICOUNTER; | 6148 | } |
| 6454 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; | 6149 | UMLAL_INST: |
| 6455 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; | 6150 | { |
| 6456 | //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]); | 6151 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 6457 | INC_PC(sizeof(b_2_thumb)); | 6152 | umlal_inst *inst_cream = (umlal_inst *)inst_base->component; |
| 6458 | goto DISPATCH; | 6153 | unsigned long long int rm = RM; |
| 6459 | } | 6154 | unsigned long long int rs = RS; |
| 6460 | B_COND_THUMB: | 6155 | unsigned long long int rst = rm * rs; |
| 6461 | { | 6156 | unsigned long long int add = ((unsigned long long) RDHI)<<32; |
| 6462 | INC_ICOUNTER; | 6157 | add += RDLO; |
| 6463 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; | 6158 | rst += add; |
| 6464 | if(CondPassed(cpu, inst_cream->cond)) | 6159 | RDLO = BITS(rst, 0, 31); |
| 6465 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; | 6160 | RDHI = BITS(rst, 32, 63); |
| 6466 | else | 6161 | |
| 6467 | cpu->Reg[15] += 2; | 6162 | if (inst_cream->S) { |
| 6468 | //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]); | 6163 | cpu->NFlag = BIT(RDHI, 31); |
| 6469 | INC_PC(sizeof(b_cond_thumb)); | 6164 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 6470 | goto DISPATCH; | 6165 | } |
| 6471 | } | 6166 | } |
| 6472 | BL_1_THUMB: | 6167 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6473 | { | 6168 | INC_PC(sizeof(umlal_inst)); |
| 6474 | INC_ICOUNTER; | 6169 | FETCH_INST; |
| 6475 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; | 6170 | GOTO_NEXT_INST; |
| 6476 | cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; | 6171 | } |
| 6477 | //cpu->Reg[15] += 2; | 6172 | UMULL_INST: |
| 6478 | //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]); | 6173 | { |
| 6479 | 6174 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | |
| 6480 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6175 | umull_inst *inst_cream = (umull_inst *)inst_base->component; |
| 6481 | INC_PC(sizeof(bl_1_thumb)); | 6176 | unsigned long long int rm = RM; |
| 6482 | FETCH_INST; | 6177 | unsigned long long int rs = RS; |
| 6483 | GOTO_NEXT_INST; | 6178 | unsigned long long int rst = rm * rs; |
| 6484 | 6179 | RDHI = BITS(rst, 32, 63); | |
| 6485 | } | 6180 | RDLO = BITS(rst, 0, 31); |
| 6486 | BL_2_THUMB: | 6181 | |
| 6487 | { | 6182 | if (inst_cream->S) { |
| 6488 | INC_ICOUNTER; | 6183 | cpu->NFlag = BIT(RDHI, 31); |
| 6489 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; | 6184 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 6490 | int tmp = ((cpu->Reg[15] + 2) | 1); | 6185 | } |
| 6491 | cpu->Reg[15] = | 6186 | } |
| 6492 | (cpu->Reg[14] + inst_cream->imm); | 6187 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6493 | cpu->Reg[14] = tmp; | 6188 | INC_PC(sizeof(umull_inst)); |
| 6494 | //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]); | 6189 | FETCH_INST; |
| 6495 | INC_PC(sizeof(bl_2_thumb)); | 6190 | GOTO_NEXT_INST; |
| 6496 | goto DISPATCH; | 6191 | } |
| 6497 | } | 6192 | B_2_THUMB: |
| 6498 | BLX_1_THUMB: | 6193 | { |
| 6499 | { | 6194 | b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; |
| 6500 | /* BLX 1 for armv5t and above */ | 6195 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6501 | INC_ICOUNTER; | 6196 | INC_PC(sizeof(b_2_thumb)); |
| 6502 | uint32 tmp = cpu->Reg[15]; | 6197 | goto DISPATCH; |
| 6503 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; | 6198 | } |
| 6504 | cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; | 6199 | B_COND_THUMB: |
| 6505 | //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); | 6200 | { |
| 6506 | cpu->Reg[14] = ((tmp + 2) | 1); | 6201 | b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; |
| 6507 | //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; | 6202 | |
| 6508 | /* switch to arm state from thumb state */ | 6203 | if(CondPassed(cpu, inst_cream->cond)) |
| 6509 | cpu->TFlag = 0; | 6204 | cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6510 | //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]); | 6205 | else |
| 6511 | INC_PC(sizeof(blx_1_thumb)); | 6206 | cpu->Reg[15] += 2; |
| 6512 | goto DISPATCH; | 6207 | |
| 6513 | } | 6208 | INC_PC(sizeof(b_cond_thumb)); |
| 6514 | 6209 | goto DISPATCH; | |
| 6515 | UQADD16_INST: | 6210 | } |
| 6516 | UQADD8_INST: | 6211 | BL_1_THUMB: |
| 6517 | UQADDSUBX_INST: | 6212 | { |
| 6518 | UQSUB16_INST: | 6213 | bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; |
| 6519 | UQSUB8_INST: | 6214 | cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6520 | UQSUBADDX_INST: | 6215 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6521 | USAD8_INST: | 6216 | INC_PC(sizeof(bl_1_thumb)); |
| 6522 | USADA8_INST: | 6217 | FETCH_INST; |
| 6523 | USAT_INST: | 6218 | GOTO_NEXT_INST; |
| 6524 | USAT16_INST: | 6219 | } |
| 6525 | USUB16_INST: | 6220 | BL_2_THUMB: |
| 6526 | USUB8_INST: | 6221 | { |
| 6527 | USUBADDX_INST: | 6222 | bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; |
| 6528 | UXTAB16_INST: | 6223 | int tmp = ((cpu->Reg[15] + 2) | 1); |
| 6529 | UXTB16_INST: | 6224 | cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm); |
| 6530 | #define VFP_INTERPRETER_IMPL | 6225 | cpu->Reg[14] = tmp; |
| 6531 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 6226 | INC_PC(sizeof(bl_2_thumb)); |
| 6532 | #undef VFP_INTERPRETER_IMPL | 6227 | goto DISPATCH; |
| 6533 | MMU_EXCEPTION: | 6228 | } |
| 6534 | { | 6229 | BLX_1_THUMB: |
| 6535 | SAVE_NZCVT; | 6230 | { |
| 6536 | cpu->abortSig = true; | 6231 | // BLX 1 for armv5t and above |
| 6537 | cpu->Aborted = ARMul_DataAbortV; | 6232 | uint32 tmp = cpu->Reg[15]; |
| 6538 | cpu->AbortAddr = addr; | 6233 | blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; |
| 6539 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; | 6234 | cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; |
| 6540 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | 6235 | cpu->Reg[14] = ((tmp + 2) | 1); |
| 6541 | cpu->NumInstrsToExecute = 0; | 6236 | cpu->TFlag = 0; |
| 6542 | return num_instrs; | 6237 | INC_PC(sizeof(blx_1_thumb)); |
| 6543 | } | 6238 | goto DISPATCH; |
| 6544 | END: | 6239 | } |
| 6545 | { | 6240 | |
| 6546 | SAVE_NZCVT; | 6241 | UQADD8_INST: |
| 6547 | cpu->NumInstrsToExecute = 0; | 6242 | UQADD16_INST: |
| 6548 | return num_instrs; | 6243 | UQADDSUBX_INST: |
| 6549 | } | 6244 | UQSUB8_INST: |
| 6550 | INIT_INST_LENGTH: | 6245 | UQSUB16_INST: |
| 6551 | { | 6246 | UQSUBADDX_INST: |
| 6552 | #if 0 | 6247 | { |
| 6553 | DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); | 6248 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 6554 | for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) | 6249 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 6555 | DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); | 6250 | |
| 6556 | DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel)); | 6251 | const u8 op2 = inst_cream->op2; |
| 6557 | #endif | 6252 | const u32 rm_val = RM; |
| 6253 | const u32 rn_val = RN; | ||
| 6254 | |||
| 6255 | u16 lo_val = 0; | ||
| 6256 | u16 hi_val = 0; | ||
| 6257 | |||
| 6258 | // UQADD16 | ||
| 6259 | if (op2 == 0x00) { | ||
| 6260 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); | ||
| 6261 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6262 | } | ||
| 6263 | // UQASX | ||
| 6264 | else if (op2 == 0x01) { | ||
| 6265 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6266 | hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); | ||
| 6267 | } | ||
| 6268 | // UQSAX | ||
| 6269 | else if (op2 == 0x02) { | ||
| 6270 | lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6271 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); | ||
| 6272 | } | ||
| 6273 | // UQSUB16 | ||
| 6274 | else if (op2 == 0x03) { | ||
| 6275 | lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); | ||
| 6276 | hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); | ||
| 6277 | } | ||
| 6278 | // UQADD8 | ||
| 6279 | else if (op2 == 0x04) { | ||
| 6280 | lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | | ||
| 6281 | ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; | ||
| 6282 | hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | | ||
| 6283 | ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; | ||
| 6284 | } | ||
| 6285 | // UQSUB8 | ||
| 6286 | else { | ||
| 6287 | lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | | ||
| 6288 | ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; | ||
| 6289 | hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | | ||
| 6290 | ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; | ||
| 6291 | } | ||
| 6292 | |||
| 6293 | RD = ((lo_val & 0xFFFF) | hi_val << 16); | ||
| 6294 | } | ||
| 6295 | |||
| 6296 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6297 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6298 | FETCH_INST; | ||
| 6299 | GOTO_NEXT_INST; | ||
| 6300 | } | ||
| 6301 | |||
| 6302 | USAD8_INST: | ||
| 6303 | USADA8_INST: | ||
| 6304 | { | ||
| 6305 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6306 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 6307 | |||
| 6308 | const u8 ra_idx = inst_cream->Ra; | ||
| 6309 | const u32 rm_val = RM; | ||
| 6310 | const u32 rn_val = RN; | ||
| 6311 | |||
| 6312 | const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); | ||
| 6313 | const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); | ||
| 6314 | const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); | ||
| 6315 | const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); | ||
| 6316 | |||
| 6317 | u32 finalDif = (diff1 + diff2 + diff3 + diff4); | ||
| 6318 | |||
| 6319 | // Op is USADA8 if true. | ||
| 6320 | if (ra_idx != 15) | ||
| 6321 | finalDif += cpu->Reg[ra_idx]; | ||
| 6322 | |||
| 6323 | RD = finalDif; | ||
| 6324 | } | ||
| 6325 | |||
| 6326 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6327 | INC_PC(sizeof(generic_arm_inst)); | ||
| 6328 | FETCH_INST; | ||
| 6329 | GOTO_NEXT_INST; | ||
| 6330 | } | ||
| 6331 | |||
| 6332 | USAT_INST: | ||
| 6333 | { | ||
| 6334 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6335 | ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; | ||
| 6336 | |||
| 6337 | u8 shift_type = inst_cream->shift_type; | ||
| 6338 | u8 shift_amount = inst_cream->imm5; | ||
| 6339 | u32 rn_val = RN; | ||
| 6340 | |||
| 6341 | // 32-bit ASR is encoded as an amount of 0. | ||
| 6342 | if (shift_type == 1 && shift_amount == 0) | ||
| 6343 | shift_amount = 31; | ||
| 6344 | |||
| 6345 | if (shift_type == 0) | ||
| 6346 | rn_val <<= shift_amount; | ||
| 6347 | else if (shift_type == 1) | ||
| 6348 | rn_val = ((s32)rn_val >> shift_amount); | ||
| 6349 | |||
| 6350 | bool saturated = false; | ||
| 6351 | rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated); | ||
| 6352 | |||
| 6353 | if (saturated) | ||
| 6354 | cpu->Cpsr |= (1 << 27); | ||
| 6355 | |||
| 6356 | RD = rn_val; | ||
| 6357 | } | ||
| 6358 | |||
| 6359 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6360 | INC_PC(sizeof(ssat_inst)); | ||
| 6361 | FETCH_INST; | ||
| 6362 | GOTO_NEXT_INST; | ||
| 6363 | } | ||
| 6364 | |||
| 6365 | USAT16_INST: | ||
| 6366 | USUB16_INST: | ||
| 6367 | USUB8_INST: | ||
| 6368 | USUBADDX_INST: | ||
| 6369 | UXTAB16_INST: | ||
| 6370 | UXTB16_INST: | ||
| 6371 | { | ||
| 6372 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6373 | uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; | ||
| 6374 | |||
| 6375 | const u8 rn_idx = inst_cream->Rn; | ||
| 6376 | const u32 rm_val = RM; | ||
| 6377 | const u32 rotation = inst_cream->rotate * 8; | ||
| 6378 | const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); | ||
| 6379 | |||
| 6380 | // UXTB16, otherwise UXTAB16 | ||
| 6381 | if (rn_idx == 15) { | ||
| 6382 | RD = rotated_rm & 0x00FF00FF; | ||
| 6383 | } else { | ||
| 6384 | const u32 rn_val = RN; | ||
| 6385 | const u8 lo_rotated = (rotated_rm & 0xFF); | ||
| 6386 | const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; | ||
| 6387 | const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; | ||
| 6388 | const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; | ||
| 6389 | |||
| 6390 | RD = ((hi_result << 16) | (lo_result & 0xFFFF)); | ||
| 6391 | } | ||
| 6392 | } | ||
| 6393 | |||
| 6394 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6395 | INC_PC(sizeof(uxtab_inst)); | ||
| 6396 | FETCH_INST; | ||
| 6397 | GOTO_NEXT_INST; | ||
| 6398 | } | ||
| 6399 | |||
| 6400 | #define VFP_INTERPRETER_IMPL | ||
| 6401 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||
| 6402 | #undef VFP_INTERPRETER_IMPL | ||
| 6403 | MMU_EXCEPTION: | ||
| 6404 | { | ||
| 6405 | SAVE_NZCVT; | ||
| 6406 | cpu->abortSig = true; | ||
| 6407 | cpu->Aborted = ARMul_DataAbortV; | ||
| 6408 | cpu->AbortAddr = addr; | ||
| 6409 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; | ||
| 6410 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 6411 | cpu->NumInstrsToExecute = 0; | ||
| 6412 | return num_instrs; | ||
| 6413 | } | ||
| 6414 | END: | ||
| 6415 | { | ||
| 6416 | SAVE_NZCVT; | ||
| 6417 | cpu->NumInstrsToExecute = 0; | ||
| 6418 | return num_instrs; | ||
| 6419 | } | ||
| 6420 | INIT_INST_LENGTH: | ||
| 6421 | { | ||
| 6558 | #if defined __GNUC__ || defined __clang__ | 6422 | #if defined __GNUC__ || defined __clang__ |
| 6559 | InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); | 6423 | InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel)); |
| 6560 | #endif | 6424 | #endif |
| 6561 | #if 0 | 6425 | cpu->NumInstrsToExecute = 0; |
| 6562 | for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++) | 6426 | return num_instrs; |
| 6563 | DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]); | 6427 | } |
| 6564 | DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]); | ||
| 6565 | DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]); | ||
| 6566 | DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]); | ||
| 6567 | #endif | ||
| 6568 | cpu->NumInstrsToExecute = 0; | ||
| 6569 | return num_instrs; | ||
| 6570 | } | ||
| 6571 | } | 6428 | } |
| 6572 | |||
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 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2011 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | ||
| 5 | * as published by the Free Software Foundation; either version 2 | ||
| 6 | * of the License, or (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_run.cpp | ||
| 20 | * @brief The dyncom run implementation for arm | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 78.77 | ||
| 23 | * @date 2011-11-20 | ||
| 24 | */ | ||
| 25 | 4 | ||
| 26 | #include <assert.h> | 5 | #include <assert.h> |
| 27 | 6 | ||
| 28 | #include "core/arm/skyeye_common/armdefs.h" | 7 | #include "core/arm/skyeye_common/armdefs.h" |
| 29 | 8 | ||
| 30 | void switch_mode(arm_core_t *core, uint32_t mode) | 9 | void switch_mode(arm_core_t *core, uint32_t mode) { |
| 31 | { | 10 | if (core->Mode == mode) |
| 32 | uint32_t tmp1, tmp2; | ||
| 33 | if (core->Mode == mode) { | ||
| 34 | //Mode not changed. | ||
| 35 | //printf("mode not changed\n"); | ||
| 36 | return; | 11 | return; |
| 37 | } | 12 | |
| 38 | //printf("%d --->>> %d\n", core->Mode, mode); | ||
| 39 | //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); | ||
| 40 | if (mode != USERBANK) { | 13 | if (mode != USERBANK) { |
| 41 | switch (core->Mode) { | 14 | switch (core->Mode) { |
| 42 | case USER32MODE: | 15 | case USER32MODE: |
| @@ -110,11 +83,8 @@ void switch_mode(arm_core_t *core, uint32_t mode) | |||
| 110 | 83 | ||
| 111 | } | 84 | } |
| 112 | core->Mode = mode; | 85 | core->Mode = mode; |
| 113 | //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); | 86 | } else { |
| 114 | //printf("\n--------------------------------------\n"); | 87 | LOG_CRITICAL(Core_ARM11, "user mode"); |
| 115 | } | ||
| 116 | else { | ||
| 117 | printf("user mode\n"); | ||
| 118 | exit(-2); | 88 | exit(-2); |
| 119 | } | 89 | } |
| 120 | } | 90 | } |
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 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project |
| 2 | * 2011 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | 4 | |
| 5 | * as published by the Free Software Foundation; either version 2 | 5 | // We can provide simple Thumb simulation by decoding the Thumb instruction into its corresponding |
| 6 | * of the License, or (at your option) any later version. | 6 | // ARM instruction, and using the existing ARM simulator. |
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /** | ||
| 19 | * @file arm_dyncom_thumb.c | ||
| 20 | * @brief The thumb dynamic interpreter | ||
| 21 | * @author Michael.Kang blackfin.kang@gmail.com | ||
| 22 | * @version 78.77 | ||
| 23 | * @date 2011-11-07 | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* We can provide simple Thumb simulation by decoding the Thumb | ||
| 27 | instruction into its corresponding ARM instruction, and using the | ||
| 28 | existing ARM simulator. */ | ||
| 29 | 7 | ||
| 30 | #include "core/arm/skyeye_common/skyeye_defs.h" | 8 | #include "core/arm/skyeye_common/skyeye_defs.h" |
| 31 | 9 | ||
| 32 | #ifndef MODET /* required for the Thumb instruction support */ | 10 | #ifndef MODET // Required for the Thumb instruction support |
| 33 | #if 1 | 11 | #if 1 |
| 34 | #error "MODET needs to be defined for the Thumb world to work" | 12 | #error "MODET needs to be defined for the Thumb world to work" |
| 35 | #else | 13 | #else |
| @@ -40,482 +18,359 @@ existing ARM simulator. */ | |||
| 40 | #include "core/arm/skyeye_common/armos.h" | 18 | #include "core/arm/skyeye_common/armos.h" |
| 41 | #include "core/arm/dyncom/arm_dyncom_thumb.h" | 19 | #include "core/arm/dyncom/arm_dyncom_thumb.h" |
| 42 | 20 | ||
| 43 | /* Decode a 16bit Thumb instruction. The instruction is in the low | 21 | // Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, |
| 44 | 16-bits of the tinstr field, with the following Thumb instruction | 22 | // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions |
| 45 | held in the high 16-bits. Passing in two Thumb instructions allows | 23 | // allows easier simulation of the special dual BL instruction. |
| 46 | easier simulation of the special dual BL instruction. */ | ||
| 47 | 24 | ||
| 48 | tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) | 25 | tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size) { |
| 49 | { | ||
| 50 | tdstate valid = t_uninitialized; | 26 | tdstate valid = t_uninitialized; |
| 51 | ARMword next_instr; | 27 | ARMword tinstr; |
| 52 | ARMword tinstr; | 28 | tinstr = instr; |
| 53 | tinstr = instr; | 29 | |
| 54 | /* The endian should be judge here */ | 30 | // The endian should be judge here |
| 55 | #if 0 | 31 | if((addr & 0x3) != 0) |
| 56 | if (state->bigendSig) { | 32 | tinstr = instr >> 16; |
| 57 | next_instr = tinstr & 0xFFFF; | 33 | else |
| 58 | tinstr >>= 16; | 34 | tinstr &= 0xFFFF; |
| 59 | } | 35 | |
| 60 | else { | 36 | *ainstr = 0xDEADC0DE; // Debugging to catch non updates |
| 61 | next_instr = tinstr >> 16; | 37 | |
| 62 | tinstr &= 0xFFFF; | 38 | switch ((tinstr & 0xF800) >> 11) { |
| 63 | } | 39 | case 0: // LSL |
| 64 | #endif | 40 | case 1: // LSR |
| 65 | if((addr & 0x3) != 0) | 41 | case 2: // ASR |
| 66 | tinstr = instr >> 16; | 42 | *ainstr = 0xE1B00000 // base opcode |
| 67 | else | 43 | | ((tinstr & 0x1800) >> (11 - 5)) // shift type |
| 68 | tinstr &= 0xFFFF; | 44 | |((tinstr & 0x07C0) << (7 - 6)) // imm5 |
| 69 | 45 | |((tinstr & 0x0038) >> 3) // Rs | |
| 70 | //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc); | 46 | |((tinstr & 0x0007) << 12); // Rd |
| 71 | #if 1 /* debugging to catch non updates */ | 47 | break; |
| 72 | *ainstr = 0xDEADC0DE; | 48 | |
| 73 | #endif | 49 | case 3: // ADD/SUB |
| 50 | { | ||
| 51 | ARMword subset[4] = { | ||
| 52 | 0xE0900000, // ADDS Rd,Rs,Rn | ||
| 53 | 0xE0500000, // SUBS Rd,Rs,Rn | ||
| 54 | 0xE2900000, // ADDS Rd,Rs,#imm3 | ||
| 55 | 0xE2500000 // SUBS Rd,Rs,#imm3 | ||
| 56 | }; | ||
| 57 | // It is quicker indexing into a table, than performing switch or conditionals: | ||
| 58 | *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode | ||
| 59 | |((tinstr & 0x01C0) >> 6) // Rn or imm3 | ||
| 60 | |((tinstr & 0x0038) << (16 - 3)) // Rs | ||
| 61 | |((tinstr & 0x0007) << (12 - 0)); // Rd | ||
| 62 | } | ||
| 63 | break; | ||
| 64 | |||
| 65 | case 4: // MOV | ||
| 66 | case 5: // CMP | ||
| 67 | case 6: // ADD | ||
| 68 | case 7: // SUB | ||
| 69 | { | ||
| 70 | ARMword subset[4] = { | ||
| 71 | 0xE3B00000, // MOVS Rd,#imm8 | ||
| 72 | 0xE3500000, // CMP Rd,#imm8 | ||
| 73 | 0xE2900000, // ADDS Rd,Rd,#imm8 | ||
| 74 | 0xE2500000, // SUBS Rd,Rd,#imm8 | ||
| 75 | }; | ||
| 76 | |||
| 77 | *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode | ||
| 78 | |((tinstr & 0x00FF) >> 0) // imm8 | ||
| 79 | |((tinstr & 0x0700) << (16 - 8)) // Rn | ||
| 80 | |((tinstr & 0x0700) << (12 - 8)); // Rd | ||
| 81 | } | ||
| 82 | break; | ||
| 83 | |||
| 84 | case 8: // Arithmetic and high register transfers | ||
| 85 | |||
| 86 | // TODO: Since the subsets for both Format 4 and Format 5 instructions are made up of | ||
| 87 | // different ARM encodings, we could save the following conditional, and just have one | ||
| 88 | // large subset | ||
| 89 | |||
| 90 | if ((tinstr & (1 << 10)) == 0) { | ||
| 91 | enum otype { | ||
| 92 | t_norm, | ||
| 93 | t_shift, | ||
| 94 | t_neg, | ||
| 95 | t_mul | ||
| 96 | }; | ||
| 97 | |||
| 98 | struct { | ||
| 99 | ARMword opcode; | ||
| 100 | otype type; | ||
| 101 | } subset[16] = { | ||
| 102 | { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs | ||
| 103 | { 0xE0300000, t_norm }, // EORS Rd,Rd,Rs | ||
| 104 | { 0xE1B00010, t_shift }, // MOVS Rd,Rd,LSL Rs | ||
| 105 | { 0xE1B00030, t_shift }, // MOVS Rd,Rd,LSR Rs | ||
| 106 | { 0xE1B00050, t_shift }, // MOVS Rd,Rd,ASR Rs | ||
| 107 | { 0xE0B00000, t_norm }, // ADCS Rd,Rd,Rs | ||
| 108 | { 0xE0D00000, t_norm }, // SBCS Rd,Rd,Rs | ||
| 109 | { 0xE1B00070, t_shift }, // MOVS Rd,Rd,ROR Rs | ||
| 110 | { 0xE1100000, t_norm }, // TST Rd,Rs | ||
| 111 | { 0xE2700000, t_neg }, // RSBS Rd,Rs,#0 | ||
| 112 | { 0xE1500000, t_norm }, // CMP Rd,Rs | ||
| 113 | { 0xE1700000, t_norm }, // CMN Rd,Rs | ||
| 114 | { 0xE1900000, t_norm }, // ORRS Rd,Rd,Rs | ||
| 115 | { 0xE0100090, t_mul }, // MULS Rd,Rd,Rs | ||
| 116 | { 0xE1D00000, t_norm }, // BICS Rd,Rd,Rs | ||
| 117 | { 0xE1F00000, t_norm } // MVNS Rd,Rs | ||
| 118 | }; | ||
| 119 | |||
| 120 | *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base | ||
| 121 | |||
| 122 | switch (subset[(tinstr & 0x03C0) >> 6].type) { | ||
| 123 | case t_norm: | ||
| 124 | *ainstr |= ((tinstr & 0x0007) << 16) // Rn | ||
| 125 | |((tinstr & 0x0007) << 12) // Rd | ||
| 126 | |((tinstr & 0x0038) >> 3); // Rs | ||
| 127 | break; | ||
| 128 | case t_shift: | ||
| 129 | *ainstr |= ((tinstr & 0x0007) << 12) // Rd | ||
| 130 | |((tinstr & 0x0007) >> 0) // Rm | ||
| 131 | |((tinstr & 0x0038) << (8 - 3)); // Rs | ||
| 132 | break; | ||
| 133 | case t_neg: | ||
| 134 | *ainstr |= ((tinstr & 0x0007) << 12) // Rd | ||
| 135 | |((tinstr & 0x0038) << (16 - 3)); // Rn | ||
| 136 | break; | ||
| 137 | case t_mul: | ||
| 138 | *ainstr |= ((tinstr & 0x0007) << 16) // Rd | ||
| 139 | |((tinstr & 0x0007) << 8) // Rs | ||
| 140 | |((tinstr & 0x0038) >> 3); // Rm | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | } else { | ||
| 144 | ARMword Rd = ((tinstr & 0x0007) >> 0); | ||
| 145 | ARMword Rs = ((tinstr & 0x0038) >> 3); | ||
| 146 | |||
| 147 | if (tinstr & (1 << 7)) | ||
| 148 | Rd += 8; | ||
| 149 | if (tinstr & (1 << 6)) | ||
| 150 | Rs += 8; | ||
| 151 | |||
| 152 | switch ((tinstr & 0x03C0) >> 6) { | ||
| 153 | case 0x1: // ADD Rd,Rd,Hs | ||
| 154 | case 0x2: // ADD Hd,Hd,Rs | ||
| 155 | case 0x3: // ADD Hd,Hd,Hs | ||
| 156 | *ainstr = 0xE0800000 // base | ||
| 157 | | (Rd << 16) // Rn | ||
| 158 | |(Rd << 12) // Rd | ||
| 159 | |(Rs << 0); // Rm | ||
| 160 | break; | ||
| 161 | case 0x5: // CMP Rd,Hs | ||
| 162 | case 0x6: // CMP Hd,Rs | ||
| 163 | case 0x7: // CMP Hd,Hs | ||
| 164 | *ainstr = 0xE1500000 // base | ||
| 165 | | (Rd << 16) // Rn | ||
| 166 | |(Rd << 12) // Rd | ||
| 167 | |(Rs << 0); // Rm | ||
| 168 | break; | ||
| 169 | case 0x9: // MOV Rd,Hs | ||
| 170 | case 0xA: // MOV Hd,Rs | ||
| 171 | case 0xB: // MOV Hd,Hs | ||
| 172 | *ainstr = 0xE1A00000 // base | ||
| 173 | | (Rd << 16) // Rn | ||
| 174 | |(Rd << 12) // Rd | ||
| 175 | |(Rs << 0); // Rm | ||
| 176 | break; | ||
| 177 | case 0xC: // BX Rs | ||
| 178 | case 0xD: // BX Hs | ||
| 179 | *ainstr = 0xE12FFF10 // base | ||
| 180 | | ((tinstr & 0x0078) >> 3); // Rd | ||
| 181 | break; | ||
| 182 | case 0x0: // UNDEFINED | ||
| 183 | case 0x4: // UNDEFINED | ||
| 184 | case 0x8: // UNDEFINED | ||
| 185 | valid = t_undefined; | ||
| 186 | break; | ||
| 187 | case 0xE: // BLX | ||
| 188 | case 0xF: // BLX | ||
| 189 | *ainstr = 0xE1200030 // base | ||
| 190 | | (Rs << 0); // Rm | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | break; | ||
| 195 | |||
| 196 | case 9: // LDR Rd,[PC,#imm8] | ||
| 197 | *ainstr = 0xE59F0000 // base | ||
| 198 | | ((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 199 | |((tinstr & 0x00FF) << (2 - 0)); // off8 | ||
| 200 | break; | ||
| 201 | |||
| 202 | case 10: | ||
| 203 | case 11: | ||
| 204 | // TODO: Format 7 and Format 8 perform the same ARM encoding, so the following could be | ||
| 205 | // merged into a single subset, saving on the following boolean: | ||
| 206 | |||
| 207 | if ((tinstr & (1 << 9)) == 0) { | ||
| 208 | ARMword subset[4] = { | ||
| 209 | 0xE7800000, // STR Rd,[Rb,Ro] | ||
| 210 | 0xE7C00000, // STRB Rd,[Rb,Ro] | ||
| 211 | 0xE7900000, // LDR Rd,[Rb,Ro] | ||
| 212 | 0xE7D00000 // LDRB Rd,[Rb,Ro] | ||
| 213 | }; | ||
| 214 | |||
| 215 | *ainstr = subset[(tinstr & 0x0C00) >> 10] // base | ||
| 216 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 217 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 218 | |((tinstr & 0x01C0) >> 6); // Ro | ||
| 219 | |||
| 220 | } else { | ||
| 221 | ARMword subset[4] = { | ||
| 222 | 0xE18000B0, // STRH Rd,[Rb,Ro] | ||
| 223 | 0xE19000D0, // LDRSB Rd,[Rb,Ro] | ||
| 224 | 0xE19000B0, // LDRH Rd,[Rb,Ro] | ||
| 225 | 0xE19000F0 // LDRSH Rd,[Rb,Ro] | ||
| 226 | }; | ||
| 227 | *ainstr = subset[(tinstr & 0x0C00) >> 10] // base | ||
| 228 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 229 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 230 | |((tinstr & 0x01C0) >> 6); // Ro | ||
| 231 | } | ||
| 232 | break; | ||
| 233 | |||
| 234 | case 12: // STR Rd,[Rb,#imm5] | ||
| 235 | case 13: // LDR Rd,[Rb,#imm5] | ||
| 236 | case 14: // STRB Rd,[Rb,#imm5] | ||
| 237 | case 15: // LDRB Rd,[Rb,#imm5] | ||
| 238 | { | ||
| 239 | ARMword subset[4] = { | ||
| 240 | 0xE5800000, // STR Rd,[Rb,#imm5] | ||
| 241 | 0xE5900000, // LDR Rd,[Rb,#imm5] | ||
| 242 | 0xE5C00000, // STRB Rd,[Rb,#imm5] | ||
| 243 | 0xE5D00000 // LDRB Rd,[Rb,#imm5] | ||
| 244 | }; | ||
| 245 | // The offset range defends on whether we are transferring a byte or word value: | ||
| 246 | *ainstr = subset[(tinstr & 0x1800) >> 11] // base | ||
| 247 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 248 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 249 | |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5 | ||
| 250 | } | ||
| 251 | break; | ||
| 252 | |||
| 253 | case 16: // STRH Rd,[Rb,#imm5] | ||
| 254 | case 17: // LDRH Rd,[Rb,#imm5] | ||
| 255 | *ainstr = ((tinstr & (1 << 11)) // base | ||
| 256 | ? 0xE1D000B0 // LDRH | ||
| 257 | : 0xE1C000B0) // STRH | ||
| 258 | |((tinstr & 0x0007) << (12 - 0)) // Rd | ||
| 259 | |((tinstr & 0x0038) << (16 - 3)) // Rb | ||
| 260 | |((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble | ||
| 261 | |((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble | ||
| 262 | break; | ||
| 263 | |||
| 264 | case 18: // STR Rd,[SP,#imm8] | ||
| 265 | case 19: // LDR Rd,[SP,#imm8] | ||
| 266 | *ainstr = ((tinstr & (1 << 11)) // base | ||
| 267 | ? 0xE59D0000 // LDR | ||
| 268 | : 0xE58D0000) // STR | ||
| 269 | |((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 270 | |((tinstr & 0x00FF) << 2); // off8 | ||
| 271 | break; | ||
| 272 | |||
| 273 | case 20: // ADD Rd,PC,#imm8 | ||
| 274 | case 21: // ADD Rd,SP,#imm8 | ||
| 275 | |||
| 276 | if ((tinstr & (1 << 11)) == 0) { | ||
| 277 | |||
| 278 | // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the | ||
| 279 | // rotate immediate field, so no shift of off8 is needed. | ||
| 280 | |||
| 281 | *ainstr = 0xE28F0F00 // base | ||
| 282 | | ((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 283 | |(tinstr & 0x00FF); // off8 | ||
| 284 | } else { | ||
| 285 | // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is needed. | ||
| 286 | *ainstr = 0xE28D0F00 // base | ||
| 287 | | ((tinstr & 0x0700) << (12 - 8)) // Rd | ||
| 288 | |(tinstr & 0x00FF); // off8 | ||
| 289 | } | ||
| 290 | break; | ||
| 291 | |||
| 292 | case 22: | ||
| 293 | case 23: | ||
| 294 | if ((tinstr & 0x0F00) == 0x0000) { | ||
| 295 | // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30): | ||
| 296 | *ainstr = ((tinstr & (1 << 7)) // base | ||
| 297 | ? 0xE24DDF00 // SUB | ||
| 298 | : 0xE28DDF00) // ADD | ||
| 299 | |(tinstr & 0x007F); // off7 | ||
| 300 | } else if ((tinstr & 0x0F00) == 0x0e00) | ||
| 301 | *ainstr = 0xEF000000 | SWI_Breakpoint; | ||
| 302 | else { | ||
| 303 | ARMword subset[4] = { | ||
| 304 | 0xE92D0000, // STMDB sp!,{rlist} | ||
| 305 | 0xE92D4000, // STMDB sp!,{rlist,lr} | ||
| 306 | 0xE8BD0000, // LDMIA sp!,{rlist} | ||
| 307 | 0xE8BD8000 // LDMIA sp!,{rlist,pc} | ||
| 308 | }; | ||
| 309 | *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base | ||
| 310 | |(tinstr & 0x00FF); // mask8 | ||
| 311 | } | ||
| 312 | break; | ||
| 313 | |||
| 314 | case 24: // STMIA | ||
| 315 | case 25: // LDMIA | ||
| 316 | *ainstr = ((tinstr & (1 << 11)) // base | ||
| 317 | ? 0xE8B00000 // LDMIA | ||
| 318 | : 0xE8A00000) // STMIA | ||
| 319 | |((tinstr & 0x0700) << (16 - 8)) // Rb | ||
| 320 | |(tinstr & 0x00FF); // mask8 | ||
| 321 | break; | ||
| 322 | |||
| 323 | case 26: // Bcc | ||
| 324 | case 27: // Bcc/SWI | ||
| 325 | if ((tinstr & 0x0F00) == 0x0F00) { | ||
| 326 | // Format 17 : SWI | ||
| 327 | *ainstr = 0xEF000000; | ||
| 328 | // Breakpoint must be handled specially. | ||
| 329 | if ((tinstr & 0x00FF) == 0x18) | ||
| 330 | *ainstr |= ((tinstr & 0x00FF) << 16); | ||
| 331 | // New breakpoint value. See gdb/arm-tdep.c | ||
| 332 | else if ((tinstr & 0x00FF) == 0xFE) | ||
| 333 | *ainstr |= SWI_Breakpoint; | ||
| 334 | else | ||
| 335 | *ainstr |= (tinstr & 0x00FF); | ||
| 336 | } else if ((tinstr & 0x0F00) != 0x0E00) | ||
| 337 | valid = t_branch; | ||
| 338 | else // UNDEFINED : cc=1110(AL) uses different format | ||
| 339 | valid = t_undefined; | ||
| 340 | |||
| 341 | break; | ||
| 342 | |||
| 343 | case 28: // B | ||
| 344 | valid = t_branch; | ||
| 345 | break; | ||
| 346 | |||
| 347 | case 29: | ||
| 348 | if(tinstr & 0x1) | ||
| 349 | valid = t_undefined; | ||
| 350 | else | ||
| 351 | valid = t_branch; | ||
| 352 | break; | ||
| 353 | |||
| 354 | case 30: // BL instruction 1 | ||
| 355 | |||
| 356 | // There is no single ARM instruction equivalent for this Thumb instruction. To keep the | ||
| 357 | // simulation simple (from the user perspective) we check if the following instruction is | ||
| 358 | // the second half of this BL, and if it is we simulate it immediately | ||
| 359 | |||
| 360 | valid = t_branch; | ||
| 361 | break; | ||
| 362 | |||
| 363 | case 31: // BL instruction 2 | ||
| 364 | |||
| 365 | // There is no single ARM instruction equivalent for this instruction. Also, it should only | ||
| 366 | // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the | ||
| 367 | // simulation of it on its own, with undefined results if r14 is not suitably initialised. | ||
| 368 | |||
| 369 | valid = t_branch; | ||
| 370 | break; | ||
| 371 | } | ||
| 372 | |||
| 373 | *inst_size = 2; | ||
| 74 | 374 | ||
| 75 | switch ((tinstr & 0xF800) >> 11) { | 375 | return valid; |
| 76 | case 0: /* LSL */ | ||
| 77 | case 1: /* LSR */ | ||
| 78 | case 2: /* ASR */ | ||
| 79 | /* Format 1 */ | ||
| 80 | *ainstr = 0xE1B00000 /* base opcode */ | ||
| 81 | | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */ | ||
| 82 | |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */ | ||
| 83 | |((tinstr & 0x0038) >> 3) /* Rs */ | ||
| 84 | |((tinstr & 0x0007) << 12); /* Rd */ | ||
| 85 | break; | ||
| 86 | case 3: /* ADD/SUB */ | ||
| 87 | /* Format 2 */ | ||
| 88 | { | ||
| 89 | ARMword subset[4] = { | ||
| 90 | 0xE0900000, /* ADDS Rd,Rs,Rn */ | ||
| 91 | 0xE0500000, /* SUBS Rd,Rs,Rn */ | ||
| 92 | 0xE2900000, /* ADDS Rd,Rs,#imm3 */ | ||
| 93 | 0xE2500000 /* SUBS Rd,Rs,#imm3 */ | ||
| 94 | }; | ||
| 95 | /* It is quicker indexing into a table, than performing switch | ||
| 96 | or conditionals: */ | ||
| 97 | *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */ | ||
| 98 | |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */ | ||
| 99 | |((tinstr & 0x0038) << (16 - 3)) /* Rs */ | ||
| 100 | |((tinstr & 0x0007) << (12 - 0)); /* Rd */ | ||
| 101 | } | ||
| 102 | break; | ||
| 103 | case 4: /* MOV */ | ||
| 104 | case 5: /* CMP */ | ||
| 105 | case 6: /* ADD */ | ||
| 106 | case 7: /* SUB */ | ||
| 107 | /* Format 3 */ | ||
| 108 | { | ||
| 109 | ARMword subset[4] = { | ||
| 110 | 0xE3B00000, /* MOVS Rd,#imm8 */ | ||
| 111 | 0xE3500000, /* CMP Rd,#imm8 */ | ||
| 112 | 0xE2900000, /* ADDS Rd,Rd,#imm8 */ | ||
| 113 | 0xE2500000, /* SUBS Rd,Rd,#imm8 */ | ||
| 114 | }; | ||
| 115 | *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */ | ||
| 116 | |((tinstr & 0x00FF) >> 0) /* imm8 */ | ||
| 117 | |((tinstr & 0x0700) << (16 - 8)) /* Rn */ | ||
| 118 | |((tinstr & 0x0700) << (12 - 8)); /* Rd */ | ||
| 119 | } | ||
| 120 | break; | ||
| 121 | case 8: /* Arithmetic and high register transfers */ | ||
| 122 | /* TODO: Since the subsets for both Format 4 and Format 5 | ||
| 123 | instructions are made up of different ARM encodings, we could | ||
| 124 | save the following conditional, and just have one large | ||
| 125 | subset. */ | ||
| 126 | if ((tinstr & (1 << 10)) == 0) { | ||
| 127 | typedef enum | ||
| 128 | { t_norm, t_shift, t_neg, t_mul }otype_t; | ||
| 129 | |||
| 130 | /* Format 4 */ | ||
| 131 | struct | ||
| 132 | { | ||
| 133 | ARMword opcode; | ||
| 134 | otype_t otype; | ||
| 135 | } | ||
| 136 | subset[16] = { | ||
| 137 | { | ||
| 138 | 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */ | ||
| 139 | { | ||
| 140 | 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */ | ||
| 141 | { | ||
| 142 | 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */ | ||
| 143 | { | ||
| 144 | 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */ | ||
| 145 | { | ||
| 146 | 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */ | ||
| 147 | { | ||
| 148 | 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */ | ||
| 149 | { | ||
| 150 | 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */ | ||
| 151 | { | ||
| 152 | 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */ | ||
| 153 | { | ||
| 154 | 0xE1100000, t_norm}, /* TST Rd,Rs */ | ||
| 155 | { | ||
| 156 | 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */ | ||
| 157 | { | ||
| 158 | 0xE1500000, t_norm}, /* CMP Rd,Rs */ | ||
| 159 | { | ||
| 160 | 0xE1700000, t_norm}, /* CMN Rd,Rs */ | ||
| 161 | { | ||
| 162 | 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */ | ||
| 163 | { | ||
| 164 | 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */ | ||
| 165 | { | ||
| 166 | 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */ | ||
| 167 | { | ||
| 168 | 0xE1F00000, t_norm} /* MVNS Rd,Rs */ | ||
| 169 | }; | ||
| 170 | *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */ | ||
| 171 | switch (subset[(tinstr & 0x03C0) >> 6].otype) { | ||
| 172 | case t_norm: | ||
| 173 | *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */ | ||
| 174 | |((tinstr & 0x0007) << 12) /* Rd */ | ||
| 175 | |((tinstr & 0x0038) >> 3); /* Rs */ | ||
| 176 | break; | ||
| 177 | case t_shift: | ||
| 178 | *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ | ||
| 179 | |((tinstr & 0x0007) >> 0) /* Rm */ | ||
| 180 | |((tinstr & 0x0038) << (8 - 3)); /* Rs */ | ||
| 181 | break; | ||
| 182 | case t_neg: | ||
| 183 | *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ | ||
| 184 | |((tinstr & 0x0038) << (16 - 3)); /* Rn */ | ||
| 185 | break; | ||
| 186 | case t_mul: | ||
| 187 | *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */ | ||
| 188 | |((tinstr & 0x0007) << 8) /* Rs */ | ||
| 189 | |((tinstr & 0x0038) >> 3); /* Rm */ | ||
| 190 | break; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | else { | ||
| 194 | /* Format 5 */ | ||
| 195 | ARMword Rd = ((tinstr & 0x0007) >> 0); | ||
| 196 | ARMword Rs = ((tinstr & 0x0038) >> 3); | ||
| 197 | if (tinstr & (1 << 7)) | ||
| 198 | Rd += 8; | ||
| 199 | if (tinstr & (1 << 6)) | ||
| 200 | Rs += 8; | ||
| 201 | switch ((tinstr & 0x03C0) >> 6) { | ||
| 202 | case 0x1: /* ADD Rd,Rd,Hs */ | ||
| 203 | case 0x2: /* ADD Hd,Hd,Rs */ | ||
| 204 | case 0x3: /* ADD Hd,Hd,Hs */ | ||
| 205 | *ainstr = 0xE0800000 /* base */ | ||
| 206 | | (Rd << 16) /* Rn */ | ||
| 207 | |(Rd << 12) /* Rd */ | ||
| 208 | |(Rs << 0); /* Rm */ | ||
| 209 | break; | ||
| 210 | case 0x5: /* CMP Rd,Hs */ | ||
| 211 | case 0x6: /* CMP Hd,Rs */ | ||
| 212 | case 0x7: /* CMP Hd,Hs */ | ||
| 213 | *ainstr = 0xE1500000 /* base */ | ||
| 214 | | (Rd << 16) /* Rn */ | ||
| 215 | |(Rd << 12) /* Rd */ | ||
| 216 | |(Rs << 0); /* Rm */ | ||
| 217 | break; | ||
| 218 | case 0x9: /* MOV Rd,Hs */ | ||
| 219 | case 0xA: /* MOV Hd,Rs */ | ||
| 220 | case 0xB: /* MOV Hd,Hs */ | ||
| 221 | *ainstr = 0xE1A00000 /* base */ | ||
| 222 | | (Rd << 16) /* Rn */ | ||
| 223 | |(Rd << 12) /* Rd */ | ||
| 224 | |(Rs << 0); /* Rm */ | ||
| 225 | break; | ||
| 226 | case 0xC: /* BX Rs */ | ||
| 227 | case 0xD: /* BX Hs */ | ||
| 228 | *ainstr = 0xE12FFF10 /* base */ | ||
| 229 | | ((tinstr & 0x0078) >> 3); /* Rd */ | ||
| 230 | break; | ||
| 231 | case 0x0: /* UNDEFINED */ | ||
| 232 | case 0x4: /* UNDEFINED */ | ||
| 233 | case 0x8: /* UNDEFINED */ | ||
| 234 | valid = t_undefined; | ||
| 235 | break; | ||
| 236 | case 0xE: /* BLX */ | ||
| 237 | case 0xF: /* BLX */ | ||
| 238 | |||
| 239 | //if (state->is_v5) { | ||
| 240 | if(1){ | ||
| 241 | //valid = t_branch; | ||
| 242 | #if 1 | ||
| 243 | *ainstr = 0xE1200030 /* base */ | ||
| 244 | |(Rs << 0); /* Rm */ | ||
| 245 | #endif | ||
| 246 | } else { | ||
| 247 | valid = t_undefined; | ||
| 248 | } | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | break; | ||
| 253 | case 9: /* LDR Rd,[PC,#imm8] */ | ||
| 254 | /* Format 6 */ | ||
| 255 | *ainstr = 0xE59F0000 /* base */ | ||
| 256 | | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 257 | |((tinstr & 0x00FF) << (2 - 0)); /* off8 */ | ||
| 258 | break; | ||
| 259 | case 10: | ||
| 260 | case 11: | ||
| 261 | /* TODO: Format 7 and Format 8 perform the same ARM encoding, so | ||
| 262 | the following could be merged into a single subset, saving on | ||
| 263 | the following boolean: */ | ||
| 264 | if ((tinstr & (1 << 9)) == 0) { | ||
| 265 | /* Format 7 */ | ||
| 266 | ARMword subset[4] = { | ||
| 267 | 0xE7800000, /* STR Rd,[Rb,Ro] */ | ||
| 268 | 0xE7C00000, /* STRB Rd,[Rb,Ro] */ | ||
| 269 | 0xE7900000, /* LDR Rd,[Rb,Ro] */ | ||
| 270 | 0xE7D00000 /* LDRB Rd,[Rb,Ro] */ | ||
| 271 | }; | ||
| 272 | *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ | ||
| 273 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 274 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 275 | |((tinstr & 0x01C0) >> 6); /* Ro */ | ||
| 276 | } | ||
| 277 | else { | ||
| 278 | /* Format 8 */ | ||
| 279 | ARMword subset[4] = { | ||
| 280 | 0xE18000B0, /* STRH Rd,[Rb,Ro] */ | ||
| 281 | 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */ | ||
| 282 | 0xE19000B0, /* LDRH Rd,[Rb,Ro] */ | ||
| 283 | 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */ | ||
| 284 | }; | ||
| 285 | *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ | ||
| 286 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 287 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 288 | |((tinstr & 0x01C0) >> 6); /* Ro */ | ||
| 289 | } | ||
| 290 | break; | ||
| 291 | case 12: /* STR Rd,[Rb,#imm5] */ | ||
| 292 | case 13: /* LDR Rd,[Rb,#imm5] */ | ||
| 293 | case 14: /* STRB Rd,[Rb,#imm5] */ | ||
| 294 | case 15: /* LDRB Rd,[Rb,#imm5] */ | ||
| 295 | /* Format 9 */ | ||
| 296 | { | ||
| 297 | ARMword subset[4] = { | ||
| 298 | 0xE5800000, /* STR Rd,[Rb,#imm5] */ | ||
| 299 | 0xE5900000, /* LDR Rd,[Rb,#imm5] */ | ||
| 300 | 0xE5C00000, /* STRB Rd,[Rb,#imm5] */ | ||
| 301 | 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */ | ||
| 302 | }; | ||
| 303 | /* The offset range defends on whether we are transferring a | ||
| 304 | byte or word value: */ | ||
| 305 | *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */ | ||
| 306 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 307 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 308 | |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */ | ||
| 309 | } | ||
| 310 | break; | ||
| 311 | case 16: /* STRH Rd,[Rb,#imm5] */ | ||
| 312 | case 17: /* LDRH Rd,[Rb,#imm5] */ | ||
| 313 | /* Format 10 */ | ||
| 314 | *ainstr = ((tinstr & (1 << 11)) /* base */ | ||
| 315 | ? 0xE1D000B0 /* LDRH */ | ||
| 316 | : 0xE1C000B0) /* STRH */ | ||
| 317 | |((tinstr & 0x0007) << (12 - 0)) /* Rd */ | ||
| 318 | |((tinstr & 0x0038) << (16 - 3)) /* Rb */ | ||
| 319 | |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */ | ||
| 320 | |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */ | ||
| 321 | break; | ||
| 322 | case 18: /* STR Rd,[SP,#imm8] */ | ||
| 323 | case 19: /* LDR Rd,[SP,#imm8] */ | ||
| 324 | /* Format 11 */ | ||
| 325 | *ainstr = ((tinstr & (1 << 11)) /* base */ | ||
| 326 | ? 0xE59D0000 /* LDR */ | ||
| 327 | : 0xE58D0000) /* STR */ | ||
| 328 | |((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 329 | |((tinstr & 0x00FF) << 2); /* off8 */ | ||
| 330 | break; | ||
| 331 | case 20: /* ADD Rd,PC,#imm8 */ | ||
| 332 | case 21: /* ADD Rd,SP,#imm8 */ | ||
| 333 | /* Format 12 */ | ||
| 334 | if ((tinstr & (1 << 11)) == 0) { | ||
| 335 | /* NOTE: The PC value used here should by word aligned */ | ||
| 336 | /* We encode shift-left-by-2 in the rotate immediate field, | ||
| 337 | so no shift of off8 is needed. */ | ||
| 338 | *ainstr = 0xE28F0F00 /* base */ | ||
| 339 | | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 340 | |(tinstr & 0x00FF); /* off8 */ | ||
| 341 | } | ||
| 342 | else { | ||
| 343 | /* We encode shift-left-by-2 in the rotate immediate field, | ||
| 344 | so no shift of off8 is needed. */ | ||
| 345 | *ainstr = 0xE28D0F00 /* base */ | ||
| 346 | | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ | ||
| 347 | |(tinstr & 0x00FF); /* off8 */ | ||
| 348 | } | ||
| 349 | break; | ||
| 350 | case 22: | ||
| 351 | case 23: | ||
| 352 | if ((tinstr & 0x0F00) == 0x0000) { | ||
| 353 | /* Format 13 */ | ||
| 354 | /* NOTE: The instruction contains a shift left of 2 | ||
| 355 | equivalent (implemented as ROR #30): */ | ||
| 356 | *ainstr = ((tinstr & (1 << 7)) /* base */ | ||
| 357 | ? 0xE24DDF00 /* SUB */ | ||
| 358 | : 0xE28DDF00) /* ADD */ | ||
| 359 | |(tinstr & 0x007F); /* off7 */ | ||
| 360 | } | ||
| 361 | else if ((tinstr & 0x0F00) == 0x0e00) | ||
| 362 | *ainstr = 0xEF000000 | SWI_Breakpoint; | ||
| 363 | else { | ||
| 364 | /* Format 14 */ | ||
| 365 | ARMword subset[4] = { | ||
| 366 | 0xE92D0000, /* STMDB sp!,{rlist} */ | ||
| 367 | 0xE92D4000, /* STMDB sp!,{rlist,lr} */ | ||
| 368 | 0xE8BD0000, /* LDMIA sp!,{rlist} */ | ||
| 369 | 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */ | ||
| 370 | }; | ||
| 371 | *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */ | ||
| 372 | |(tinstr & 0x00FF); /* mask8 */ | ||
| 373 | } | ||
| 374 | break; | ||
| 375 | case 24: /* STMIA */ | ||
| 376 | case 25: /* LDMIA */ | ||
| 377 | /* Format 15 */ | ||
| 378 | *ainstr = ((tinstr & (1 << 11)) /* base */ | ||
| 379 | ? 0xE8B00000 /* LDMIA */ | ||
| 380 | : 0xE8A00000) /* STMIA */ | ||
| 381 | |((tinstr & 0x0700) << (16 - 8)) /* Rb */ | ||
| 382 | |(tinstr & 0x00FF); /* mask8 */ | ||
| 383 | break; | ||
| 384 | case 26: /* Bcc */ | ||
| 385 | case 27: /* Bcc/SWI */ | ||
| 386 | if ((tinstr & 0x0F00) == 0x0F00) { | ||
| 387 | #if 0 | ||
| 388 | if (tinstr == (ARMul_ABORTWORD & 0xffff) && | ||
| 389 | state->AbortAddr == pc) { | ||
| 390 | *ainstr = ARMul_ABORTWORD; | ||
| 391 | break; | ||
| 392 | } | ||
| 393 | #endif | ||
| 394 | /* Format 17 : SWI */ | ||
| 395 | *ainstr = 0xEF000000; | ||
| 396 | /* Breakpoint must be handled specially. */ | ||
| 397 | if ((tinstr & 0x00FF) == 0x18) | ||
| 398 | *ainstr |= ((tinstr & 0x00FF) << 16); | ||
| 399 | /* New breakpoint value. See gdb/arm-tdep.c */ | ||
| 400 | else if ((tinstr & 0x00FF) == 0xFE) | ||
| 401 | *ainstr |= SWI_Breakpoint; | ||
| 402 | else | ||
| 403 | *ainstr |= (tinstr & 0x00FF); | ||
| 404 | } | ||
| 405 | else if ((tinstr & 0x0F00) != 0x0E00) { | ||
| 406 | /* Format 16 */ | ||
| 407 | #if 0 | ||
| 408 | int doit = FALSE; | ||
| 409 | /* TODO: Since we are doing a switch here, we could just add | ||
| 410 | the SWI and undefined instruction checks into this | ||
| 411 | switch to same on a couple of conditionals: */ | ||
| 412 | switch ((tinstr & 0x0F00) >> 8) { | ||
| 413 | case EQ: | ||
| 414 | doit = ZFLAG; | ||
| 415 | break; | ||
| 416 | case NE: | ||
| 417 | doit = !ZFLAG; | ||
| 418 | break; | ||
| 419 | case VS: | ||
| 420 | doit = VFLAG; | ||
| 421 | break; | ||
| 422 | case VC: | ||
| 423 | doit = !VFLAG; | ||
| 424 | break; | ||
| 425 | case MI: | ||
| 426 | doit = NFLAG; | ||
| 427 | break; | ||
| 428 | case PL: | ||
| 429 | doit = !NFLAG; | ||
| 430 | break; | ||
| 431 | case CS: | ||
| 432 | doit = CFLAG; | ||
| 433 | break; | ||
| 434 | case CC: | ||
| 435 | doit = !CFLAG; | ||
| 436 | break; | ||
| 437 | case HI: | ||
| 438 | doit = (CFLAG && !ZFLAG); | ||
| 439 | break; | ||
| 440 | case LS: | ||
| 441 | doit = (!CFLAG || ZFLAG); | ||
| 442 | break; | ||
| 443 | case GE: | ||
| 444 | doit = ((!NFLAG && !VFLAG) | ||
| 445 | || (NFLAG && VFLAG)); | ||
| 446 | break; | ||
| 447 | case LT: | ||
| 448 | doit = ((NFLAG && !VFLAG) | ||
| 449 | || (!NFLAG && VFLAG)); | ||
| 450 | break; | ||
| 451 | case GT: | ||
| 452 | doit = ((!NFLAG && !VFLAG && !ZFLAG) | ||
| 453 | || (NFLAG && VFLAG && !ZFLAG)); | ||
| 454 | break; | ||
| 455 | case LE: | ||
| 456 | doit = ((NFLAG && !VFLAG) | ||
| 457 | || (!NFLAG && VFLAG)) || ZFLAG; | ||
| 458 | break; | ||
| 459 | } | ||
| 460 | if (doit) { | ||
| 461 | state->Reg[15] = (pc + 4 | ||
| 462 | + (((tinstr & 0x7F) << 1) | ||
| 463 | | ((tinstr & (1 << 7)) ? | ||
| 464 | 0xFFFFFF00 : 0))); | ||
| 465 | FLUSHPIPE; | ||
| 466 | } | ||
| 467 | #endif | ||
| 468 | valid = t_branch; | ||
| 469 | } | ||
| 470 | else /* UNDEFINED : cc=1110(AL) uses different format */ | ||
| 471 | valid = t_undefined; | ||
| 472 | break; | ||
| 473 | case 28: /* B */ | ||
| 474 | /* Format 18 */ | ||
| 475 | #if 0 | ||
| 476 | state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1) | ||
| 477 | | ((tinstr & (1 << 10)) ? | ||
| 478 | 0xFFFFF800 : 0))); | ||
| 479 | #endif | ||
| 480 | //FLUSHPIPE; | ||
| 481 | valid = t_branch; | ||
| 482 | break; | ||
| 483 | case 29: | ||
| 484 | if(tinstr & 0x1) | ||
| 485 | valid = t_undefined; | ||
| 486 | else{ | ||
| 487 | /* BLX 1 for armv5t and above */ | ||
| 488 | //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); | ||
| 489 | valid = t_branch; | ||
| 490 | } | ||
| 491 | break; | ||
| 492 | case 30: /* BL instruction 1 */ | ||
| 493 | /* Format 19 */ | ||
| 494 | /* There is no single ARM instruction equivalent for this Thumb | ||
| 495 | instruction. To keep the simulation simple (from the user | ||
| 496 | perspective) we check if the following instruction is the | ||
| 497 | second half of this BL, and if it is we simulate it | ||
| 498 | immediately. */ | ||
| 499 | valid = t_branch; | ||
| 500 | break; | ||
| 501 | case 31: /* BL instruction 2 */ | ||
| 502 | /* Format 19 */ | ||
| 503 | /* There is no single ARM instruction equivalent for this | ||
| 504 | instruction. Also, it should only ever be matched with the | ||
| 505 | fmt19 "BL instruction 1" instruction. However, we do allow | ||
| 506 | the simulation of it on its own, with undefined results if | ||
| 507 | r14 is not suitably initialised. */ | ||
| 508 | { | ||
| 509 | #if 0 | ||
| 510 | ARMword tmp = (pc + 2); | ||
| 511 | state->Reg[15] = | ||
| 512 | (state->Reg[14] + ((tinstr & 0x07FF) << 1)); | ||
| 513 | state->Reg[14] = (tmp | 1); | ||
| 514 | #endif | ||
| 515 | valid = t_branch; | ||
| 516 | } | ||
| 517 | break; | ||
| 518 | } | ||
| 519 | *inst_size = 2; | ||
| 520 | return valid; | ||
| 521 | } | 376 | } |