summaryrefslogtreecommitdiffstats
path: root/src/core/arm/dyncom
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-01-03 04:24:12 +0100
committerbunnei <bunneidev@gmail.com>2018-01-03 04:24:12 +0100
commitb172f0d770486d4367fbea22906a5e908ef621e8 (patch)
tree6a564c23ed8f52c16c50942803f4a69fd0047f6c /src/core/arm/dyncom
parentvm_manager: Use a more reasonable MAX_ADDRESS size. (diff)
downloadyuzu-b172f0d770486d4367fbea22906a5e908ef621e8.tar
yuzu-b172f0d770486d4367fbea22906a5e908ef621e8.tar.gz
yuzu-b172f0d770486d4367fbea22906a5e908ef621e8.tar.bz2
yuzu-b172f0d770486d4367fbea22906a5e908ef621e8.tar.lz
yuzu-b172f0d770486d4367fbea22906a5e908ef621e8.tar.xz
yuzu-b172f0d770486d4367fbea22906a5e908ef621e8.tar.zst
yuzu-b172f0d770486d4367fbea22906a5e908ef621e8.zip
Diffstat (limited to 'src/core/arm/dyncom')
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp132
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h46
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp478
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h36
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp4578
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.h9
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h48
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp390
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h49
-rw-r--r--src/core/arm/dyncom/arm_dyncom_trans.cpp1887
-rw-r--r--src/core/arm/dyncom/arm_dyncom_trans.h494
11 files changed, 0 insertions, 8147 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
deleted file mode 100644
index 5ebf7a2f1..000000000
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <cstring>
-#include <memory>
-#include "core/arm/dyncom/arm_dyncom.h"
-#include "core/arm/dyncom/arm_dyncom_interpreter.h"
-#include "core/arm/dyncom/arm_dyncom_run.h"
-#include "core/arm/dyncom/arm_dyncom_trans.h"
-#include "core/arm/skyeye_common/armstate.h"
-#include "core/arm/skyeye_common/armsupp.h"
-#include "core/arm/skyeye_common/vfp/vfp.h"
-#include "core/core.h"
-#include "core/core_timing.h"
-
-ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) {
- state = std::make_unique<ARMul_State>(initial_mode);
-}
-
-ARM_DynCom::~ARM_DynCom() {}
-
-void ARM_DynCom::ClearInstructionCache() {
- state->instruction_cache.clear();
- trans_cache_buf_top = 0;
-}
-
-void ARM_DynCom::SetPC(u64 pc) {
- state->Reg[15] = pc;
-}
-
-void ARM_DynCom::PageTableChanged() {
- ClearInstructionCache();
-}
-
-u64 ARM_DynCom::GetPC() const {
- return state->Reg[15];
-}
-
-u64 ARM_DynCom::GetReg(int index) const {
- return state->Reg[index];
-}
-
-void ARM_DynCom::SetReg(int index, u64 value) {
- state->Reg[index] = value;
-}
-
-const u128& ARM_DynCom::GetExtReg(int index) const {
- return {};
-}
-
-void ARM_DynCom::SetExtReg(int index, u128& value) {
-}
-
-u32 ARM_DynCom::GetVFPReg(int index) const {
- return state->ExtReg[index];
-}
-
-void ARM_DynCom::SetVFPReg(int index, u32 value) {
- state->ExtReg[index] = value;
-}
-
-u32 ARM_DynCom::GetVFPSystemReg(VFPSystemRegister reg) const {
- return state->VFP[reg];
-}
-
-void ARM_DynCom::SetVFPSystemReg(VFPSystemRegister reg, u32 value) {
- state->VFP[reg] = value;
-}
-
-u32 ARM_DynCom::GetCPSR() const {
- return state->Cpsr;
-}
-
-void ARM_DynCom::SetCPSR(u32 cpsr) {
- state->Cpsr = cpsr;
-}
-
-u32 ARM_DynCom::GetCP15Register(CP15Register reg) {
- return state->CP15[reg];
-}
-
-void ARM_DynCom::SetCP15Register(CP15Register reg, u32 value) {
- state->CP15[reg] = value;
-}
-
-VAddr ARM_DynCom::GetTlsAddress() const {
- return {};
-}
-
-void ARM_DynCom::SetTlsAddress(VAddr /*address*/) {
-}
-
-void ARM_DynCom::ExecuteInstructions(int num_instructions) {
- state->NumInstrsToExecute = num_instructions;
-
- // Dyncom only breaks on instruction dispatch. This only happens on every instruction when
- // executing one instruction at a time. Otherwise, if a block is being executed, more
- // instructions may actually be executed than specified.
- unsigned ticks_executed = InterpreterMainLoop(state.get());
- CoreTiming::AddTicks(ticks_executed);
-}
-
-void ARM_DynCom::SaveContext(ThreadContext& ctx) {
- memcpy(ctx.cpu_registers, state->Reg.data(), sizeof(ctx.cpu_registers));
- memcpy(ctx.fpu_registers, state->ExtReg.data(), sizeof(ctx.fpu_registers));
-
- ctx.sp = state->Reg[13];
- ctx.lr = state->Reg[14];
- ctx.pc = state->Reg[15];
- ctx.cpsr = state->Cpsr;
-
- ctx.fpscr = state->VFP[VFP_FPSCR];
- ctx.fpexc = state->VFP[VFP_FPEXC];
-}
-
-void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
- memcpy(state->Reg.data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
- memcpy(state->ExtReg.data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
-
- state->Reg[13] = ctx.sp;
- state->Reg[14] = ctx.lr;
- state->Reg[15] = ctx.pc;
- state->Cpsr = ctx.cpsr;
-
- state->VFP[VFP_FPSCR] = ctx.fpscr;
- state->VFP[VFP_FPEXC] = ctx.fpexc;
-}
-
-void ARM_DynCom::PrepareReschedule() {
- state->NumInstrsToExecute = 0;
-}
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
deleted file mode 100644
index cc3c0f3da..000000000
--- a/src/core/arm/dyncom/arm_dyncom.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <memory>
-#include "common/common_types.h"
-#include "core/arm/arm_interface.h"
-#include "core/arm/skyeye_common/arm_regformat.h"
-#include "core/arm/skyeye_common/armstate.h"
-
-class ARM_DynCom final : public ARM_Interface {
-public:
- ARM_DynCom(PrivilegeMode initial_mode);
- ~ARM_DynCom();
-
- void ClearInstructionCache() override;
- void PageTableChanged() override;
-
- void SetPC(u64 pc) override;
- u64 GetPC() const override;
- u64 GetReg(int index) const override;
- void SetReg(int index, u64 value) override;
- const u128& GetExtReg(int index) const override;
- void SetExtReg(int index, u128& value) override;
- u32 GetVFPReg(int index) const override;
- void SetVFPReg(int index, u32 value) override;
- u32 GetVFPSystemReg(VFPSystemRegister reg) const override;
- void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override;
- u32 GetCPSR() const override;
- void SetCPSR(u32 cpsr) override;
- u32 GetCP15Register(CP15Register reg) override;
- void SetCP15Register(CP15Register reg, u32 value) override;
- VAddr GetTlsAddress() const override;
- void SetTlsAddress(VAddr address) override;
-
- void SaveContext(ThreadContext& ctx) override;
- void LoadContext(const ThreadContext& ctx) override;
-
- void PrepareReschedule() override;
- void ExecuteInstructions(int num_instructions) override;
-
-private:
- std::unique_ptr<ARMul_State> state;
-};
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
deleted file mode 100644
index dcfcd6561..000000000
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "core/arm/dyncom/arm_dyncom_dec.h"
-#include "core/arm/skyeye_common/armsupp.h"
-
-// clang-format off
-const InstructionSetEncodingItem arm_instruction[] = {
- { "vmla", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
- { "vmls", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
- { "vnmla", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
- { "vnmls", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
- { "vnmul", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
- { "vmul", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
- { "vadd", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
- { "vsub", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
- { "vdiv", 5, ARMVFP2, { 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }},
- { "vmov(i)", 4, ARMVFP3, { 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0 }},
- { "vmov(r)", 5, ARMVFP3, { 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }},
- { "vabs", 5, ARMVFP2, { 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }},
- { "vneg", 5, ARMVFP2, { 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0 }},
- { "vsqrt", 5, ARMVFP2, { 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }},
- { "vcmp", 5, ARMVFP2, { 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
- { "vcmp2", 5, ARMVFP2, { 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40 }},
- { "vcvt(bds)", 5, ARMVFP2, { 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0 }},
- { "vcvt(bff)", 6, ARMVFP3, { 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 5, 6, 6, 1 }},
- { "vcvt(bfi)", 5, ARMVFP2, { 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }},
- { "vmovbrs", 3, ARMVFP2, { 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10 }},
- { "vmsr", 2, ARMVFP2, { 20, 27, 0xEE, 0, 11, 0xA10 }},
- { "vmovbrc", 4, ARMVFP2, { 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0, 4, 0x10 }},
- { "vmrs", 2, ARMVFP2, { 20, 27, 0xEF, 0, 11, 0xA10 }},
- { "vmovbcr", 4, ARMVFP2, { 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0, 4, 0x10 }},
- { "vmovbrrss", 3, ARMVFP2, { 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1 }},
- { "vmovbrrd", 3, ARMVFP2, { 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1 }},
- { "vstr", 3, ARMVFP2, { 24, 27, 0xD, 20, 21, 0, 9, 11, 5 }},
- { "vpush", 3, ARMVFP2, { 23, 27, 0x1A, 16, 21, 0x2D, 9, 11, 5 }},
- { "vstm", 3, ARMVFP2, { 25, 27, 0x6, 20, 20, 0, 9, 11, 5 }},
- { "vpop", 3, ARMVFP2, { 23, 27, 0x19, 16, 21, 0x3D, 9, 11, 5 }},
- { "vldr", 3, ARMVFP2, { 24, 27, 0xD, 20, 21, 1, 9, 11, 5 }},
- { "vldm", 3, ARMVFP2, { 25, 27, 0x6, 20, 20, 1, 9, 11, 5 }},
-
- { "srs", 4, 6, { 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005 }},
- { "rfe", 4, 6, { 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a }},
- { "bkpt", 2, 3, { 20, 27, 0x00000012, 4, 7, 0x00000007 }},
- { "blx", 1, 3, { 25, 31, 0x0000007d }},
- { "cps", 3, 6, { 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000 }},
- { "pld", 4, 4, { 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f }},
- { "setend", 2, 6, { 16, 31, 0x0000f101, 4, 7, 0x00000000 }},
- { "clrex", 1, 6, { 0, 31, 0xf57ff01f }},
- { "rev16", 2, 6, { 16, 27, 0x000006bf, 4, 11, 0x000000fb }},
- { "usad8", 3, 6, { 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001 }},
- { "sxtb", 2, 6, { 16, 27, 0x000006af, 4, 7, 0x00000007 }},
- { "uxtb", 2, 6, { 16, 27, 0x000006ef, 4, 7, 0x00000007 }},
- { "sxth", 2, 6, { 16, 27, 0x000006bf, 4, 7, 0x00000007 }},
- { "sxtb16", 2, 6, { 16, 27, 0x0000068f, 4, 7, 0x00000007 }},
- { "uxth", 2, 6, { 16, 27, 0x000006ff, 4, 7, 0x00000007 }},
- { "uxtb16", 2, 6, { 16, 27, 0x000006cf, 4, 7, 0x00000007 }},
- { "cpy", 2, 6, { 20, 27, 0x0000001a, 4, 11, 0x00000000 }},
- { "uxtab", 2, 6, { 20, 27, 0x0000006e, 4, 9, 0x00000007 }},
- { "ssub8", 2, 6, { 20, 27, 0x00000061, 4, 7, 0x0000000f }},
- { "shsub8", 2, 6, { 20, 27, 0x00000063, 4, 7, 0x0000000f }},
- { "ssubaddx", 2, 6, { 20, 27, 0x00000061, 4, 7, 0x00000005 }},
- { "strex", 2, 6, { 20, 27, 0x00000018, 4, 7, 0x00000009 }},
- { "strexb", 2, 7, { 20, 27, 0x0000001c, 4, 7, 0x00000009 }},
- { "swp", 2, 0, { 20, 27, 0x00000010, 4, 7, 0x00000009 }},
- { "swpb", 2, 0, { 20, 27, 0x00000014, 4, 7, 0x00000009 }},
- { "ssub16", 2, 6, { 20, 27, 0x00000061, 4, 7, 0x00000007 }},
- { "ssat16", 2, 6, { 20, 27, 0x0000006a, 4, 7, 0x00000003 }},
- { "shsubaddx", 2, 6, { 20, 27, 0x00000063, 4, 7, 0x00000005 }},
- { "qsubaddx", 2, 6, { 20, 27, 0x00000062, 4, 7, 0x00000005 }},
- { "shaddsubx", 2, 6, { 20, 27, 0x00000063, 4, 7, 0x00000003 }},
- { "shadd8", 2, 6, { 20, 27, 0x00000063, 4, 7, 0x00000009 }},
- { "shadd16", 2, 6, { 20, 27, 0x00000063, 4, 7, 0x00000001 }},
- { "sel", 2, 6, { 20, 27, 0x00000068, 4, 7, 0x0000000b }},
- { "saddsubx", 2, 6, { 20, 27, 0x00000061, 4, 7, 0x00000003 }},
- { "sadd8", 2, 6, { 20, 27, 0x00000061, 4, 7, 0x00000009 }},
- { "sadd16", 2, 6, { 20, 27, 0x00000061, 4, 7, 0x00000001 }},
- { "shsub16", 2, 6, { 20, 27, 0x00000063, 4, 7, 0x00000007 }},
- { "umaal", 2, 6, { 20, 27, 0x00000004, 4, 7, 0x00000009 }},
- { "uxtab16", 2, 6, { 20, 27, 0x0000006c, 4, 7, 0x00000007 }},
- { "usubaddx", 2, 6, { 20, 27, 0x00000065, 4, 7, 0x00000005 }},
- { "usub8", 2, 6, { 20, 27, 0x00000065, 4, 7, 0x0000000f }},
- { "usub16", 2, 6, { 20, 27, 0x00000065, 4, 7, 0x00000007 }},
- { "usat16", 2, 6, { 20, 27, 0x0000006e, 4, 7, 0x00000003 }},
- { "usada8", 2, 6, { 20, 27, 0x00000078, 4, 7, 0x00000001 }},
- { "uqsubaddx", 2, 6, { 20, 27, 0x00000066, 4, 7, 0x00000005 }},
- { "uqsub8", 2, 6, { 20, 27, 0x00000066, 4, 7, 0x0000000f }},
- { "uqsub16", 2, 6, { 20, 27, 0x00000066, 4, 7, 0x00000007 }},
- { "uqaddsubx", 2, 6, { 20, 27, 0x00000066, 4, 7, 0x00000003 }},
- { "uqadd8", 2, 6, { 20, 27, 0x00000066, 4, 7, 0x00000009 }},
- { "uqadd16", 2, 6, { 20, 27, 0x00000066, 4, 7, 0x00000001 }},
- { "sxtab", 2, 6, { 20, 27, 0x0000006a, 4, 7, 0x00000007 }},
- { "uhsubaddx", 2, 6, { 20, 27, 0x00000067, 4, 7, 0x00000005 }},
- { "uhsub8", 2, 6, { 20, 27, 0x00000067, 4, 7, 0x0000000f }},
- { "uhsub16", 2, 6, { 20, 27, 0x00000067, 4, 7, 0x00000007 }},
- { "uhaddsubx", 2, 6, { 20, 27, 0x00000067, 4, 7, 0x00000003 }},
- { "uhadd8", 2, 6, { 20, 27, 0x00000067, 4, 7, 0x00000009 }},
- { "uhadd16", 2, 6, { 20, 27, 0x00000067, 4, 7, 0x00000001 }},
- { "uaddsubx", 2, 6, { 20, 27, 0x00000065, 4, 7, 0x00000003 }},
- { "uadd8", 2, 6, { 20, 27, 0x00000065, 4, 7, 0x00000009 }},
- { "uadd16", 2, 6, { 20, 27, 0x00000065, 4, 7, 0x00000001 }},
- { "sxtah", 2, 6, { 20, 27, 0x0000006b, 4, 7, 0x00000007 }},
- { "sxtab16", 2, 6, { 20, 27, 0x00000068, 4, 7, 0x00000007 }},
- { "qadd8", 2, 6, { 20, 27, 0x00000062, 4, 7, 0x00000009 }},
- { "bxj", 2, 5, { 20, 27, 0x00000012, 4, 7, 0x00000002 }},
- { "clz", 2, 3, { 20, 27, 0x00000016, 4, 7, 0x00000001 }},
- { "uxtah", 2, 6, { 20, 27, 0x0000006f, 4, 7, 0x00000007 }},
- { "bx", 2, 2, { 20, 27, 0x00000012, 4, 7, 0x00000001 }},
- { "rev", 2, 6, { 20, 27, 0x0000006b, 4, 7, 0x00000003 }},
- { "blx", 2, 3, { 20, 27, 0x00000012, 4, 7, 0x00000003 }},
- { "revsh", 2, 6, { 20, 27, 0x0000006f, 4, 7, 0x0000000b }},
- { "qadd", 2, 4, { 20, 27, 0x00000010, 4, 7, 0x00000005 }},
- { "qadd16", 2, 6, { 20, 27, 0x00000062, 4, 7, 0x00000001 }},
- { "qaddsubx", 2, 6, { 20, 27, 0x00000062, 4, 7, 0x00000003 }},
- { "ldrex", 2, 0, { 20, 27, 0x00000019, 4, 7, 0x00000009 }},
- { "qdadd", 2, 4, { 20, 27, 0x00000014, 4, 7, 0x00000005 }},
- { "qdsub", 2, 4, { 20, 27, 0x00000016, 4, 7, 0x00000005 }},
- { "qsub", 2, 4, { 20, 27, 0x00000012, 4, 7, 0x00000005 }},
- { "ldrexb", 2, 7, { 20, 27, 0x0000001d, 4, 7, 0x00000009 }},
- { "qsub8", 2, 6, { 20, 27, 0x00000062, 4, 7, 0x0000000f }},
- { "qsub16", 2, 6, { 20, 27, 0x00000062, 4, 7, 0x00000007 }},
- { "smuad", 4, 6, { 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }},
- { "smmul", 4, 6, { 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001 }},
- { "smusd", 4, 6, { 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001 }},
- { "smlsd", 3, 6, { 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001 }},
- { "smlsld", 3, 6, { 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001 }},
- { "smmla", 3, 6, { 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001 }},
- { "smmls", 3, 6, { 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001 }},
- { "smlald", 3, 6, { 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001 }},
- { "smlad", 3, 6, { 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001 }},
- { "smlaw", 3, 4, { 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000 }},
- { "smulw", 3, 4, { 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002 }},
- { "pkhtb", 2, 6, { 20, 27, 0x00000068, 4, 6, 0x00000005 }},
- { "pkhbt", 2, 6, { 20, 27, 0x00000068, 4, 6, 0x00000001 }},
- { "smul", 3, 4, { 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }},
- { "smlalxy", 3, 4, { 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }},
- { "smla", 3, 4, { 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }},
- { "mcrr", 1, 6, { 20, 27, 0x000000c4 }},
- { "mrrc", 1, 6, { 20, 27, 0x000000c5 }},
- { "cmp", 2, 0, { 26, 27, 0x00000000, 20, 24, 0x00000015 }},
- { "tst", 2, 0, { 26, 27, 0x00000000, 20, 24, 0x00000011 }},
- { "teq", 2, 0, { 26, 27, 0x00000000, 20, 24, 0x00000013 }},
- { "cmn", 2, 0, { 26, 27, 0x00000000, 20, 24, 0x00000017 }},
- { "smull", 2, 0, { 21, 27, 0x00000006, 4, 7, 0x00000009 }},
- { "umull", 2, 0, { 21, 27, 0x00000004, 4, 7, 0x00000009 }},
- { "umlal", 2, 0, { 21, 27, 0x00000005, 4, 7, 0x00000009 }},
- { "smlal", 2, 0, { 21, 27, 0x00000007, 4, 7, 0x00000009 }},
- { "mul", 2, 0, { 21, 27, 0x00000000, 4, 7, 0x00000009 }},
- { "mla", 2, 0, { 21, 27, 0x00000001, 4, 7, 0x00000009 }},
- { "ssat", 2, 6, { 21, 27, 0x00000035, 4, 5, 0x00000001 }},
- { "usat", 2, 6, { 21, 27, 0x00000037, 4, 5, 0x00000001 }},
- { "mrs", 4, 0, { 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000 }},
- { "msr", 3, 0, { 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000 }},
- { "and", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000000 }},
- { "bic", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x0000000e }},
- { "ldm", 3, 0, { 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000 }},
- { "eor", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000001 }},
- { "add", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000004 }},
- { "rsb", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000003 }},
- { "rsc", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000007 }},
- { "sbc", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000006 }},
- { "adc", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000005 }},
- { "sub", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x00000002 }},
- { "orr", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x0000000c }},
- { "mvn", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x0000000f }},
- { "mov", 2, 0, { 26, 27, 0x00000000, 21, 24, 0x0000000d }},
- { "stm", 2, 0, { 25, 27, 0x00000004, 20, 22, 0x00000004 }},
- { "ldm", 4, 0, { 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001 }},
- { "ldrsh", 3, 2, { 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f }},
- { "stm", 3, 0, { 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000 }},
- { "ldm", 3, 0, { 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001 }},
- { "ldrsb", 3, 2, { 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d }},
- { "strd", 3, 4, { 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f }},
- { "ldrh", 3, 0, { 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b }},
- { "strh", 3, 0, { 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b }},
- { "ldrd", 3, 4, { 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d }},
- { "strt", 3, 0, { 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002 }},
- { "strbt", 3, 0, { 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006 }},
- { "ldrbt", 3, 0, { 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007 }},
- { "ldrt", 3, 0, { 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003 }},
- { "mrc", 3, 6, { 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001 }},
- { "mcr", 3, 0, { 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001 }},
- { "msr", 3, 0, { 23, 27, 0x00000006, 20, 21, 0x00000002, 22, 22, 0x00000001 }},
- { "msr", 4, 0, { 23, 27, 0x00000006, 20, 21, 0x00000002, 22, 22, 0x00000000, 16, 19, 0x00000004 }},
- { "msr", 5, 0, { 23, 27, 0x00000006, 20, 21, 0x00000002, 22, 22, 0x00000000, 19, 19, 0x00000001, 16, 17, 0x00000000 }},
- { "msr", 4, 0, { 23, 27, 0x00000006, 20, 21, 0x00000002, 22, 22, 0x00000000, 16, 17, 0x00000001 }},
- { "msr", 4, 0, { 23, 27, 0x00000006, 20, 21, 0x00000002, 22, 22, 0x00000000, 17, 17, 0x00000001 }},
- { "ldrb", 3, 0, { 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001 }},
- { "strb", 3, 0, { 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000 }},
- { "ldr", 4, 0, { 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }},
- { "ldrcond", 3, 0, { 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001 }},
- { "str", 3, 0, { 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000 }},
- { "cdp", 2, 0, { 24, 27, 0x0000000e, 4, 4, 0x00000000 }},
- { "stc", 2, 0, { 25, 27, 0x00000006, 20, 20, 0x00000000 }},
- { "ldc", 2, 0, { 25, 27, 0x00000006, 20, 20, 0x00000001 }},
- { "ldrexd", 2, ARMV6K, { 20, 27, 0x0000001B, 4, 7, 0x00000009 }},
- { "strexd", 2, ARMV6K, { 20, 27, 0x0000001A, 4, 7, 0x00000009 }},
- { "ldrexh", 2, ARMV6K, { 20, 27, 0x0000001F, 4, 7, 0x00000009 }},
- { "strexh", 2, ARMV6K, { 20, 27, 0x0000001E, 4, 7, 0x00000009 }},
- { "nop", 5, ARMV6K, { 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000000 }},
- { "yield", 5, ARMV6K, { 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000001 }},
- { "wfe", 5, ARMV6K, { 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000002 }},
- { "wfi", 5, ARMV6K, { 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000003 }},
- { "sev", 5, ARMV6K, { 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000004 }},
- { "swi", 1, 0, { 24, 27, 0x0000000f }},
- { "bbl", 1, 0, { 25, 27, 0x00000005 }},
-};
-
-
-const InstructionSetEncodingItem arm_exclusion_code[] = {
- { "vmla", 0, ARMVFP2, { 0 }},
- { "vmls", 0, ARMVFP2, { 0 }},
- { "vnmla", 0, ARMVFP2, { 0 }},
- { "vnmls", 0, ARMVFP2, { 0 }},
- { "vnmul", 0, ARMVFP2, { 0 }},
- { "vmul", 0, ARMVFP2, { 0 }},
- { "vadd", 0, ARMVFP2, { 0 }},
- { "vsub", 0, ARMVFP2, { 0 }},
- { "vdiv", 0, ARMVFP2, { 0 }},
- { "vmov(i)", 0, ARMVFP3, { 0 }},
- { "vmov(r)", 0, ARMVFP3, { 0 }},
- { "vabs", 0, ARMVFP2, { 0 }},
- { "vneg", 0, ARMVFP2, { 0 }},
- { "vsqrt", 0, ARMVFP2, { 0 }},
- { "vcmp", 0, ARMVFP2, { 0 }},
- { "vcmp2", 0, ARMVFP2, { 0 }},
- { "vcvt(bff)", 0, ARMVFP3, { 4, 4, 1 }},
- { "vcvt(bds)", 0, ARMVFP2, { 0 }},
- { "vcvt(bfi)", 0, ARMVFP2, { 0 }},
- { "vmovbrs", 0, ARMVFP2, { 0 }},
- { "vmsr", 0, ARMVFP2, { 0 }},
- { "vmovbrc", 0, ARMVFP2, { 0 }},
- { "vmrs", 0, ARMVFP2, { 0 }},
- { "vmovbcr", 0, ARMVFP2, { 0 }},
- { "vmovbrrss", 0, ARMVFP2, { 0 }},
- { "vmovbrrd", 0, ARMVFP2, { 0 }},
- { "vstr", 0, ARMVFP2, { 0 }},
- { "vpush", 0, ARMVFP2, { 0 }},
- { "vstm", 0, ARMVFP2, { 0 }},
- { "vpop", 0, ARMVFP2, { 0 }},
- { "vldr", 0, ARMVFP2, { 0 }},
- { "vldm", 0, ARMVFP2, { 0 }},
-
- { "srs", 0, 6, { 0 }},
- { "rfe", 0, 6, { 0 }},
- { "bkpt", 0, 3, { 0 }},
- { "blx", 0, 3, { 0 }},
- { "cps", 0, 6, { 0 }},
- { "pld", 0, 4, { 0 }},
- { "setend", 0, 6, { 0 }},
- { "clrex", 0, 6, { 0 }},
- { "rev16", 0, 6, { 0 }},
- { "usad8", 0, 6, { 0 }},
- { "sxtb", 0, 6, { 0 }},
- { "uxtb", 0, 6, { 0 }},
- { "sxth", 0, 6, { 0 }},
- { "sxtb16", 0, 6, { 0 }},
- { "uxth", 0, 6, { 0 }},
- { "uxtb16", 0, 6, { 0 }},
- { "cpy", 0, 6, { 0 }},
- { "uxtab", 0, 6, { 0 }},
- { "ssub8", 0, 6, { 0 }},
- { "shsub8", 0, 6, { 0 }},
- { "ssubaddx", 0, 6, { 0 }},
- { "strex", 0, 6, { 0 }},
- { "strexb", 0, 7, { 0 }},
- { "swp", 0, 0, { 0 }},
- { "swpb", 0, 0, { 0 }},
- { "ssub16", 0, 6, { 0 }},
- { "ssat16", 0, 6, { 0 }},
- { "shsubaddx", 0, 6, { 0 }},
- { "qsubaddx", 0, 6, { 0 }},
- { "shaddsubx", 0, 6, { 0 }},
- { "shadd8", 0, 6, { 0 }},
- { "shadd16", 0, 6, { 0 }},
- { "sel", 0, 6, { 0 }},
- { "saddsubx", 0, 6, { 0 }},
- { "sadd8", 0, 6, { 0 }},
- { "sadd16", 0, 6, { 0 }},
- { "shsub16", 0, 6, { 0 }},
- { "umaal", 0, 6, { 0 }},
- { "uxtab16", 0, 6, { 0 }},
- { "usubaddx", 0, 6, { 0 }},
- { "usub8", 0, 6, { 0 }},
- { "usub16", 0, 6, { 0 }},
- { "usat16", 0, 6, { 0 }},
- { "usada8", 0, 6, { 0 }},
- { "uqsubaddx", 0, 6, { 0 }},
- { "uqsub8", 0, 6, { 0 }},
- { "uqsub16", 0, 6, { 0 }},
- { "uqaddsubx", 0, 6, { 0 }},
- { "uqadd8", 0, 6, { 0 }},
- { "uqadd16", 0, 6, { 0 }},
- { "sxtab", 0, 6, { 0 }},
- { "uhsubaddx", 0, 6, { 0 }},
- { "uhsub8", 0, 6, { 0 }},
- { "uhsub16", 0, 6, { 0 }},
- { "uhaddsubx", 0, 6, { 0 }},
- { "uhadd8", 0, 6, { 0 }},
- { "uhadd16", 0, 6, { 0 }},
- { "uaddsubx", 0, 6, { 0 }},
- { "uadd8", 0, 6, { 0 }},
- { "uadd16", 0, 6, { 0 }},
- { "sxtah", 0, 6, { 0 }},
- { "sxtab16", 0, 6, { 0 }},
- { "qadd8", 0, 6, { 0 }},
- { "bxj", 0, 5, { 0 }},
- { "clz", 0, 3, { 0 }},
- { "uxtah", 0, 6, { 0 }},
- { "bx", 0, 2, { 0 }},
- { "rev", 0, 6, { 0 }},
- { "blx", 0, 3, { 0 }},
- { "revsh", 0, 6, { 0 }},
- { "qadd", 0, 4, { 0 }},
- { "qadd16", 0, 6, { 0 }},
- { "qaddsubx", 0, 6, { 0 }},
- { "ldrex", 0, 0, { 0 }},
- { "qdadd", 0, 4, { 0 }},
- { "qdsub", 0, 4, { 0 }},
- { "qsub", 0, 4, { 0 }},
- { "ldrexb", 0, 7, { 0 }},
- { "qsub8", 0, 6, { 0 }},
- { "qsub16", 0, 6, { 0 }},
- { "smuad", 0, 6, { 0 }},
- { "smmul", 0, 6, { 0 }},
- { "smusd", 0, 6, { 0 }},
- { "smlsd", 0, 6, { 0 }},
- { "smlsld", 0, 6, { 0 }},
- { "smmla", 0, 6, { 0 }},
- { "smmls", 0, 6, { 0 }},
- { "smlald", 0, 6, { 0 }},
- { "smlad", 0, 6, { 0 }},
- { "smlaw", 0, 4, { 0 }},
- { "smulw", 0, 4, { 0 }},
- { "pkhtb", 0, 6, { 0 }},
- { "pkhbt", 0, 6, { 0 }},
- { "smul", 0, 4, { 0 }},
- { "smlal", 0, 4, { 0 }},
- { "smla", 0, 4, { 0 }},
- { "mcrr", 0, 6, { 0 }},
- { "mrrc", 0, 6, { 0 }},
- { "cmp", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "tst", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "teq", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "cmn", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "smull", 0, 0, { 0 }},
- { "umull", 0, 0, { 0 }},
- { "umlal", 0, 0, { 0 }},
- { "smlal", 0, 0, { 0 }},
- { "mul", 0, 0, { 0 }},
- { "mla", 0, 0, { 0 }},
- { "ssat", 0, 6, { 0 }},
- { "usat", 0, 6, { 0 }},
- { "mrs", 0, 0, { 0 }},
- { "msr", 0, 0, { 0 }},
- { "and", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "bic", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "ldm", 0, 0, { 0 }},
- { "eor", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "add", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "rsb", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "rsc", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "sbc", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "adc", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "sub", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "orr", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "mvn", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "mov", 3, 0, { 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000 }},
- { "stm", 0, 0, { 0 }},
- { "ldm", 0, 0, { 0 }},
- { "ldrsh", 0, 2, { 0 }},
- { "stm", 0, 0, { 0 }},
- { "ldm", 0, 0, { 0 }},
- { "ldrsb", 0, 2, { 0 }},
- { "strd", 0, 4, { 0 }},
- { "ldrh", 0, 0, { 0 }},
- { "strh", 0, 0, { 0 }},
- { "ldrd", 0, 4, { 0 }},
- { "strt", 0, 0, { 0 }},
- { "strbt", 0, 0, { 0 }},
- { "ldrbt", 0, 0, { 0 }},
- { "ldrt", 0, 0, { 0 }},
- { "mrc", 0, 6, { 0 }},
- { "mcr", 0, 0, { 0 }},
- { "msr", 0, 0, { 0 }},
- { "msr", 0, 0, { 0 }},
- { "msr", 0, 0, { 0 }},
- { "msr", 0, 0, { 0 }},
- { "msr", 0, 0, { 0 }},
- { "ldrb", 0, 0, { 0 }},
- { "strb", 0, 0, { 0 }},
- { "ldr", 0, 0, { 0 }},
- { "ldrcond", 1, 0, { 28, 31, 0x0000000e }},
- { "str", 0, 0, { 0 }},
- { "cdp", 0, 0, { 0 }},
- { "stc", 0, 0, { 0 }},
- { "ldc", 0, 0, { 0 }},
- { "ldrexd", 0, ARMV6K, { 0 }},
- { "strexd", 0, ARMV6K, { 0 }},
- { "ldrexh", 0, ARMV6K, { 0 }},
- { "strexh", 0, ARMV6K, { 0 }},
- { "nop", 0, ARMV6K, { 0 }},
- { "yield", 0, ARMV6K, { 0 }},
- { "wfe", 0, ARMV6K, { 0 }},
- { "wfi", 0, ARMV6K, { 0 }},
- { "sev", 0, ARMV6K, { 0 }},
- { "swi", 0, 0, { 0 }},
- { "bbl", 0, 0, { 0 }},
-
- { "bl_1_thumb", 0, INVALID, { 0 }}, // Should be table[-4]
- { "bl_2_thumb", 0, INVALID, { 0 }}, // Should be located at the end of the table[-3]
- { "blx_1_thumb", 0, INVALID, { 0 }}, // Should be located at table[-2]
- { "invalid", 0, INVALID, { 0 }}
-};
-// clang-format on
-
-ARMDecodeStatus DecodeARMInstruction(u32 instr, int* idx) {
- int n = 0;
- int base = 0;
- int instr_slots = sizeof(arm_instruction) / sizeof(InstructionSetEncodingItem);
- ARMDecodeStatus ret = ARMDecodeStatus::FAILURE;
-
- for (int i = 0; i < instr_slots; i++) {
- n = arm_instruction[i].attribute_value;
- base = 0;
-
- // 3DS has no VFP3 support
- if (arm_instruction[i].version == ARMVFP3)
- continue;
-
- while (n) {
- if (arm_instruction[i].content[base + 1] == 31 &&
- arm_instruction[i].content[base] == 0) {
- // clrex
- if (instr != arm_instruction[i].content[base + 2]) {
- break;
- }
- } else if (BITS(instr, arm_instruction[i].content[base],
- arm_instruction[i].content[base + 1]) !=
- arm_instruction[i].content[base + 2]) {
- break;
- }
- base += 3;
- n--;
- }
-
- // All conditions are satisfied.
- if (n == 0)
- ret = ARMDecodeStatus::SUCCESS;
-
- if (ret == ARMDecodeStatus::SUCCESS) {
- n = arm_exclusion_code[i].attribute_value;
- if (n != 0) {
- base = 0;
- while (n) {
- if (BITS(instr, arm_exclusion_code[i].content[base],
- arm_exclusion_code[i].content[base + 1]) !=
- arm_exclusion_code[i].content[base + 2]) {
- break;
- }
- base += 3;
- n--;
- }
-
- // All conditions are satisfied.
- if (n == 0)
- ret = ARMDecodeStatus::FAILURE;
- }
- }
-
- if (ret == ARMDecodeStatus::SUCCESS) {
- *idx = i;
- return ret;
- }
- }
- return ret;
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
deleted file mode 100644
index 1dcf7ecd1..000000000
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 Michael Kang, 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "common/common_types.h"
-
-enum class ARMDecodeStatus { SUCCESS, FAILURE };
-
-ARMDecodeStatus DecodeARMInstruction(u32 instr, int* idx);
-
-struct InstructionSetEncodingItem {
- const char* name;
- int attribute_value;
- int version;
- u32 content[21];
-};
-
-// ARM versions
-enum {
- INVALID = 0,
- ARMALL,
- ARMV4,
- ARMV4T,
- ARMV5T,
- ARMV5TE,
- ARMV5TEJ,
- ARMV6,
- ARM1176JZF_S,
- ARMVFP2,
- ARMVFP3,
- ARMV6K,
-};
-
-extern const InstructionSetEncodingItem arm_instruction[];
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
deleted file mode 100644
index fc2d6aabc..000000000
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ /dev/null
@@ -1,4578 +0,0 @@
-// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#define CITRA_IGNORE_EXIT(x)
-
-#include <algorithm>
-#include <cinttypes>
-#include <cstdio>
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "common/microprofile.h"
-#include "core/arm/dyncom/arm_dyncom_dec.h"
-#include "core/arm/dyncom/arm_dyncom_interpreter.h"
-#include "core/arm/dyncom/arm_dyncom_run.h"
-#include "core/arm/dyncom/arm_dyncom_thumb.h"
-#include "core/arm/dyncom/arm_dyncom_trans.h"
-#include "core/arm/skyeye_common/armstate.h"
-#include "core/arm/skyeye_common/armsupp.h"
-#include "core/arm/skyeye_common/vfp/vfp.h"
-#include "core/gdbstub/gdbstub.h"
-#include "core/hle/svc.h"
-#include "core/memory.h"
-
-#define RM BITS(sht_oper, 0, 3)
-#define RS BITS(sht_oper, 8, 11)
-
-#define glue(x, y) x##y
-#define DPO(s) glue(DataProcessingOperands, s)
-#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
-#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
-#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
-#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
-
-static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
- const bool n_flag = cpu->NFlag != 0;
- const bool z_flag = cpu->ZFlag != 0;
- const bool c_flag = cpu->CFlag != 0;
- const bool v_flag = cpu->VFlag != 0;
-
- switch (cond) {
- case ConditionCode::EQ:
- return z_flag;
- case ConditionCode::NE:
- return !z_flag;
- case ConditionCode::CS:
- return c_flag;
- case ConditionCode::CC:
- return !c_flag;
- case ConditionCode::MI:
- return n_flag;
- case ConditionCode::PL:
- return !n_flag;
- case ConditionCode::VS:
- return v_flag;
- case ConditionCode::VC:
- return !v_flag;
- case ConditionCode::HI:
- return (c_flag && !z_flag);
- case ConditionCode::LS:
- return (!c_flag || z_flag);
- case ConditionCode::GE:
- return (n_flag == v_flag);
- case ConditionCode::LT:
- return (n_flag != v_flag);
- case ConditionCode::GT:
- return (!z_flag && (n_flag == v_flag));
- case ConditionCode::LE:
- return (z_flag || (n_flag != v_flag));
- case ConditionCode::AL:
- case ConditionCode::NV: // Unconditional
- return true;
- }
-
- return false;
-}
-
-static unsigned int DPO(Immediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int immed_8 = BITS(sht_oper, 0, 7);
- unsigned int rotate_imm = BITS(sht_oper, 8, 11);
- unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
- if (rotate_imm == 0)
- cpu->shifter_carry_out = cpu->CFlag;
- else
- cpu->shifter_carry_out = BIT(shifter_operand, 31);
- return shifter_operand;
-}
-
-static unsigned int DPO(Register)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- return shifter_operand;
-}
-
-static unsigned int DPO(LogicalShiftLeftByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- int shift_imm = BITS(sht_oper, 7, 11);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- if (shift_imm == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else {
- shifter_operand = rm << shift_imm;
- cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(LogicalShiftLeftByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- int shifter_operand;
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = rm << BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
- } else if (BITS(rs, 0, 7) == 32) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 0);
- } else {
- shifter_operand = 0;
- cpu->shifter_carry_out = 0;
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(LogicalShiftRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = rm >> shift_imm;
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(LogicalShiftRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = rm >> BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
- } else if (BITS(rs, 0, 7) == 32) {
- shifter_operand = 0;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = 0;
- cpu->shifter_carry_out = 0;
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(ArithmeticShiftRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- if (BIT(rm, 31) == 0)
- shifter_operand = 0;
- else
- shifter_operand = 0xFFFFFFFF;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = static_cast<int>(rm) >> shift_imm;
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(ArithmeticShiftRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 7) < 32) {
- shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
- } else {
- if (BIT(rm, 31) == 0)
- shifter_operand = 0;
- else
- shifter_operand = 0xffffffff;
- cpu->shifter_carry_out = BIT(rm, 31);
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(RotateRightByImmediate)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int shifter_operand;
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- int shift_imm = BITS(sht_oper, 7, 11);
- if (shift_imm == 0) {
- shifter_operand = (cpu->CFlag << 31) | (rm >> 1);
- cpu->shifter_carry_out = BIT(rm, 0);
- } else {
- shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
- cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
- }
- return shifter_operand;
-}
-
-static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sht_oper) {
- unsigned int rm = CHECK_READ_REG15(cpu, RM);
- unsigned int rs = CHECK_READ_REG15(cpu, RS);
- unsigned int shifter_operand;
- if (BITS(rs, 0, 7) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = cpu->CFlag;
- } else if (BITS(rs, 0, 4) == 0) {
- shifter_operand = rm;
- cpu->shifter_carry_out = BIT(rm, 31);
- } else {
- shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
- cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
- }
- return shifter_operand;
-}
-
-#define DEBUG_MSG \
- LOG_DEBUG(Core_ARM, "inst is %x", inst); \
- CITRA_IGNORE_EXIT(0)
-
-#define LnSWoUB(s) glue(LnSWoUB, s)
-#define MLnS(s) glue(MLnS, s)
-#define LdnStM(s) glue(LdnStM, s)
-
-#define W_BIT BIT(inst, 21)
-#define U_BIT BIT(inst, 23)
-#define I_BIT BIT(inst, 25)
-#define P_BIT BIT(inst, 24)
-#define OFFSET_12 BITS(inst, 0, 11)
-
-static void LnSWoUB(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
-
- if (U_BIT)
- addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
- else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
-
- virt_addr = addr;
-}
-
-static void LnSWoUB(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int addr;
-
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
-
- virt_addr = addr;
-}
-
-static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
-
- if (U_BIT)
- cpu->Reg[Rn] += OFFSET_12;
- else
- cpu->Reg[Rn] -= OFFSET_12;
-
- virt_addr = addr;
-}
-
-static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
-
- if (U_BIT)
- addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
- else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
-
- virt_addr = addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
-}
-
-static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int addr;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
-
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
-
- virt_addr = addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
-}
-
-static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int addr;
-
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
-
- virt_addr = addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- cpu->Reg[Rn] = addr;
- }
-}
-
-static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index = 0;
- unsigned int addr;
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
-
- switch (shift) {
- case 0:
- index = rm << shift_imm;
- break;
- case 1:
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0) { // ASR #32
- if (BIT(rm, 31) == 1)
- index = 0xFFFFFFFF;
- else
- index = 0;
- } else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- if (shift_imm == 0) {
- index = (cpu->CFlag << 31) | (rm >> 1);
- } else {
- index = ROTATE_RIGHT_32(rm, shift_imm);
- }
- break;
- }
-
- if (U_BIT)
- addr = rn + index;
- else
- addr = rn - index;
-
- virt_addr = addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
-}
-
-static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index = 0;
- unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
-
- switch (shift) {
- case 0:
- index = rm << shift_imm;
- break;
- case 1:
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0) { // ASR #32
- if (BIT(rm, 31) == 1)
- index = 0xFFFFFFFF;
- else
- index = 0;
- } else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- if (shift_imm == 0) {
- index = (cpu->CFlag << 31) | (rm >> 1);
- } else {
- index = ROTATE_RIGHT_32(rm, shift_imm);
- }
- break;
- }
-
- virt_addr = addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT)
- cpu->Reg[Rn] += index;
- else
- cpu->Reg[Rn] -= index;
- }
-}
-
-static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
-
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT) {
- cpu->Reg[Rn] += rm;
- } else {
- cpu->Reg[Rn] -= rm;
- }
- }
-}
-
-static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int addr;
-
- unsigned int offset_8 = (immedH << 4) | immedL;
-
- if (U_BIT)
- addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
- else
- addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
-
- virt_addr = addr;
-}
-
-static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int addr;
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
-
- if (U_BIT)
- addr = rn + rm;
- else
- addr = rn - rm;
-
- virt_addr = addr;
-}
-
-static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int addr;
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int offset_8 = (immedH << 4) | immedL;
-
- if (U_BIT)
- addr = rn + offset_8;
- else
- addr = rn - offset_8;
-
- virt_addr = addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)))
- cpu->Reg[Rn] = addr;
-}
-
-static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
-
- virt_addr = rn;
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- unsigned int offset_8 = (immedH << 4) | immedL;
- if (U_BIT)
- rn += offset_8;
- else
- rn -= offset_8;
-
- cpu->Reg[Rn] = rn;
- }
-}
-
-static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
-
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
-
- if (CondPassed(cpu, BITS(inst, 28, 31))) {
- if (U_BIT)
- cpu->Reg[Rn] += rm;
- else
- cpu->Reg[Rn] -= rm;
- }
-}
-
-static void LdnStM(DecrementBefore)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
-
- while (i) {
- if (i & 1)
- count++;
- i = i >> 1;
- }
-
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn) - count * 4;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
- cpu->Reg[Rn] -= count * 4;
-}
-
-static void LdnStM(IncrementBefore)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
-
- while (i) {
- if (i & 1)
- count++;
- i = i >> 1;
- }
-
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn) + 4;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
- cpu->Reg[Rn] += count * 4;
-}
-
-static void LdnStM(IncrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
-
- while (i) {
- if (i & 1)
- count++;
- i = i >> 1;
- }
-
- virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21))
- cpu->Reg[Rn] += count * 4;
-}
-
-static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int i = BITS(inst, 0, 15);
- int count = 0;
- while (i) {
- if (i & 1)
- count++;
- i = i >> 1;
- }
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
- unsigned int start_addr = rn - count * 4 + 4;
-
- virt_addr = start_addr;
-
- if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
- cpu->Reg[Rn] -= count * 4;
- }
-}
-
-static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst,
- unsigned int& virt_addr) {
- unsigned int shift = BITS(inst, 5, 6);
- unsigned int shift_imm = BITS(inst, 7, 11);
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
- unsigned int index = 0;
- unsigned int addr;
- unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
- unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
-
- switch (shift) {
- case 0:
- index = rm << shift_imm;
- break;
- case 1:
- if (shift_imm == 0) {
- index = 0;
- } else {
- index = rm >> shift_imm;
- }
- break;
- case 2:
- if (shift_imm == 0) { // ASR #32
- if (BIT(rm, 31) == 1)
- index = 0xFFFFFFFF;
- else
- index = 0;
- } else {
- index = static_cast<int>(rm) >> shift_imm;
- }
- break;
- case 3:
- if (shift_imm == 0) {
- index = (cpu->CFlag << 31) | (rm >> 1);
- } else {
- index = ROTATE_RIGHT_32(rm, shift_imm);
- }
- break;
- }
-
- if (U_BIT) {
- addr = rn + index;
- } else
- addr = rn - index;
-
- virt_addr = addr;
-}
-
-shtop_fp_t GetShifterOp(unsigned int inst) {
- if (BIT(inst, 25)) {
- return DPO(Immediate);
- } else if (BITS(inst, 4, 11) == 0) {
- return DPO(Register);
- } else if (BITS(inst, 4, 6) == 0) {
- return DPO(LogicalShiftLeftByImmediate);
- } else if (BITS(inst, 4, 7) == 1) {
- return DPO(LogicalShiftLeftByRegister);
- } else if (BITS(inst, 4, 6) == 2) {
- return DPO(LogicalShiftRightByImmediate);
- } else if (BITS(inst, 4, 7) == 3) {
- return DPO(LogicalShiftRightByRegister);
- } else if (BITS(inst, 4, 6) == 4) {
- return DPO(ArithmeticShiftRightByImmediate);
- } else if (BITS(inst, 4, 7) == 5) {
- return DPO(ArithmeticShiftRightByRegister);
- } else if (BITS(inst, 4, 6) == 6) {
- return DPO(RotateRightByImmediate);
- } else if (BITS(inst, 4, 7) == 7) {
- return DPO(RotateRightByRegister);
- }
- return nullptr;
-}
-
-get_addr_fp_t GetAddressingOp(unsigned int inst) {
- if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
- return LnSWoUB(ImmediateOffset);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterOffset);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterOffset);
- } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
- return LnSWoUB(ImmediatePreIndexed);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
- return LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
- return LnSWoUB(RegisterPostIndexed);
- } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
- return LnSWoUB(ScaledRegisterPostIndexed);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 &&
- BIT(inst, 4) == 1) {
- return MLnS(ImmediateOffset);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 &&
- BIT(inst, 4) == 1) {
- return MLnS(RegisterOffset);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 &&
- BIT(inst, 4) == 1) {
- return MLnS(ImmediatePreIndexed);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 &&
- BIT(inst, 4) == 1) {
- return MLnS(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 &&
- BIT(inst, 4) == 1) {
- return MLnS(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 &&
- BIT(inst, 4) == 1) {
- return MLnS(RegisterPostIndexed);
- } else if (BITS(inst, 23, 27) == 0x11) {
- return LdnStM(IncrementAfter);
- } else if (BITS(inst, 23, 27) == 0x13) {
- return LdnStM(IncrementBefore);
- } else if (BITS(inst, 23, 27) == 0x10) {
- return LdnStM(DecrementAfter);
- } else if (BITS(inst, 23, 27) == 0x12) {
- return LdnStM(DecrementBefore);
- }
- return nullptr;
-}
-
-// Specialized for LDRT, LDRBT, STRT, and STRBT, which have specific addressing mode requirements
-get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst) {
- if (BITS(inst, 25, 27) == 2) {
- return LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- return LnSWoUB(ScaledRegisterPostIndexed);
- }
- // Reaching this would indicate the thumb version
- // of this instruction, however the 3DS CPU doesn't
- // support this variant (the 3DS CPU is only ARMv6K,
- // while this variant is added in ARMv6T2).
- // So it's sufficient for citra to not implement this.
- return nullptr;
-}
-
-enum { FETCH_SUCCESS, FETCH_FAILURE };
-
-static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size,
- ARM_INST_PTR* ptr_inst_base) {
- // Check if in Thumb mode
- ThumbDecodeStatus ret = TranslateThumbInstruction(addr, inst, arm_inst, inst_size);
- if (ret == ThumbDecodeStatus::BRANCH) {
- int inst_index;
- int table_length = static_cast<int>(arm_instruction_trans_len);
- u32 tinstr = GetThumbInstruction(inst, addr);
-
- switch ((tinstr & 0xF800) >> 11) {
- case 26:
- case 27:
- if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)) {
- inst_index = table_length - 4;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- } else {
- LOG_ERROR(Core_ARM, "thumb decoder error");
- }
- break;
- case 28:
- // Branch 2, unconditional branch
- inst_index = table_length - 5;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
-
- case 8:
- case 29:
- // For BLX 1 thumb instruction
- inst_index = table_length - 1;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 30:
- // For BL 1 thumb instruction
- inst_index = table_length - 3;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- case 31:
- // For BL 2 thumb instruction
- inst_index = table_length - 2;
- *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
- break;
- default:
- ret = ThumbDecodeStatus::UNDEFINED;
- break;
- }
- }
- return ret;
-}
-
-enum { KEEP_GOING, FETCH_EXCEPTION };
-
-MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64));
-
-static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr,
- ARM_INST_PTR& inst_base) {
- u32 inst_size = 4;
- u32 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
-
- // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM
- // instruction
- if (cpu->TFlag) {
- u32 arm_inst;
- ThumbDecodeStatus state =
- DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
-
- // We have translated the Thumb branch instruction in the Thumb decoder
- if (state == ThumbDecodeStatus::BRANCH) {
- return inst_size;
- }
- inst = arm_inst;
- }
-
- int idx;
- if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
- LOG_ERROR(Core_ARM, "Decode failure.\tPC: [0x%08" PRIX32 "]\tInstruction: %08" PRIX32,
- phys_addr, inst);
- LOG_ERROR(Core_ARM, "cpsr=0x%" PRIX32 ", cpu->TFlag=%d, r15=0x%08" PRIX32, cpu->Cpsr,
- cpu->TFlag, cpu->Reg[15]);
- CITRA_IGNORE_EXIT(-1);
- }
- inst_base = arm_instruction_trans[idx](inst, idx);
-
- return inst_size;
-}
-
-static int InterpreterTranslateBlock(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
- MICROPROFILE_SCOPE(DynCom_Decode);
-
- // Decode instruction, get index
- // Allocate memory and init InsCream
- // Go on next, until terminal instruction
- // Save start addr of basicblock in CreamCache
- ARM_INST_PTR inst_base = nullptr;
- TransExtData ret = TransExtData::NON_BRANCH;
- int size = 0; // instruction size of basic block
- bb_start = trans_cache_buf_top;
-
- u32 phys_addr = addr;
- u32 pc_start = cpu->Reg[15];
-
- while (ret == TransExtData::NON_BRANCH) {
- unsigned int inst_size = InterpreterTranslateInstruction(cpu, phys_addr, inst_base);
-
- size++;
-
- phys_addr += inst_size;
-
- if ((phys_addr & 0xfff) == 0) {
- inst_base->br = TransExtData::END_OF_PAGE;
- }
- ret = inst_base->br;
- };
-
- cpu->instruction_cache[pc_start] = bb_start;
-
- return KEEP_GOING;
-}
-
-static int InterpreterTranslateSingle(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
- MICROPROFILE_SCOPE(DynCom_Decode);
-
- ARM_INST_PTR inst_base = nullptr;
- bb_start = trans_cache_buf_top;
-
- u32 phys_addr = addr;
- u32 pc_start = cpu->Reg[15];
-
- InterpreterTranslateInstruction(cpu, phys_addr, inst_base);
-
- if (inst_base->br == TransExtData::NON_BRANCH) {
- inst_base->br = TransExtData::SINGLE_STEP;
- }
-
- cpu->instruction_cache[pc_start] = bb_start;
-
- return KEEP_GOING;
-}
-
-static int clz(unsigned int x) {
- int n;
- if (x == 0)
- return (32);
- n = 1;
- if ((x >> 16) == 0) {
- n = n + 16;
- x = x << 16;
- }
- if ((x >> 24) == 0) {
- n = n + 8;
- x = x << 8;
- }
- if ((x >> 28) == 0) {
- n = n + 4;
- x = x << 4;
- }
- if ((x >> 30) == 0) {
- n = n + 2;
- x = x << 2;
- }
- n = n - (x >> 31);
- return n;
-}
-
-MICROPROFILE_DEFINE(DynCom_Execute, "DynCom", "Execute", MP_RGB(255, 0, 0));
-
-unsigned InterpreterMainLoop(ARMul_State* cpu) {
- MICROPROFILE_SCOPE(DynCom_Execute);
-
- GDBStub::BreakpointAddress breakpoint_data;
-
-#undef RM
-#undef RS
-
-#define CRn inst_cream->crn
-#define OPCODE_1 inst_cream->opcode_1
-#define OPCODE_2 inst_cream->opcode_2
-#define CRm inst_cream->crm
-#define RD cpu->Reg[inst_cream->Rd]
-#define RD2 cpu->Reg[inst_cream->Rd + 1]
-#define RN cpu->Reg[inst_cream->Rn]
-#define RM cpu->Reg[inst_cream->Rm]
-#define RS cpu->Reg[inst_cream->Rs]
-#define RDHI cpu->Reg[inst_cream->RdHi]
-#define RDLO cpu->Reg[inst_cream->RdLo]
-#define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
-#define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
-#define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
-
-#define FETCH_INST \
- if (inst_base->br != TransExtData::NON_BRANCH) \
- goto DISPATCH; \
- inst_base = (arm_inst*)&trans_cache_buf[ptr]
-
-#define INC_PC(l) ptr += sizeof(arm_inst) + l
-#define INC_PC_STUB ptr += sizeof(arm_inst)
-
-#define GDB_BP_CHECK \
- cpu->Cpsr &= ~(1 << 5); \
- cpu->Cpsr |= cpu->TFlag << 5; \
- if (GDBStub::IsServerEnabled()) { \
- if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && \
- PC == breakpoint_data.address)) { \
- GDBStub::Break(); \
- goto END; \
- } \
- }
-
-// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
-// clunky switch statement.
-#if defined __GNUC__ || defined __clang__
-#define GOTO_NEXT_INST \
- GDB_BP_CHECK; \
- if (num_instrs >= cpu->NumInstrsToExecute) \
- goto END; \
- num_instrs++; \
- goto* InstLabel[inst_base->idx]
-#else
-#define GOTO_NEXT_INST \
- GDB_BP_CHECK; \
- if (num_instrs >= cpu->NumInstrsToExecute) \
- goto END; \
- num_instrs++; \
- switch (inst_base->idx) { \
- case 0: \
- goto VMLA_INST; \
- case 1: \
- goto VMLS_INST; \
- case 2: \
- goto VNMLA_INST; \
- case 3: \
- goto VNMLS_INST; \
- case 4: \
- goto VNMUL_INST; \
- case 5: \
- goto VMUL_INST; \
- case 6: \
- goto VADD_INST; \
- case 7: \
- goto VSUB_INST; \
- case 8: \
- goto VDIV_INST; \
- case 9: \
- goto VMOVI_INST; \
- case 10: \
- goto VMOVR_INST; \
- case 11: \
- goto VABS_INST; \
- case 12: \
- goto VNEG_INST; \
- case 13: \
- goto VSQRT_INST; \
- case 14: \
- goto VCMP_INST; \
- case 15: \
- goto VCMP2_INST; \
- case 16: \
- goto VCVTBDS_INST; \
- case 17: \
- goto VCVTBFF_INST; \
- case 18: \
- goto VCVTBFI_INST; \
- case 19: \
- goto VMOVBRS_INST; \
- case 20: \
- goto VMSR_INST; \
- case 21: \
- goto VMOVBRC_INST; \
- case 22: \
- goto VMRS_INST; \
- case 23: \
- goto VMOVBCR_INST; \
- case 24: \
- goto VMOVBRRSS_INST; \
- case 25: \
- goto VMOVBRRD_INST; \
- case 26: \
- goto VSTR_INST; \
- case 27: \
- goto VPUSH_INST; \
- case 28: \
- goto VSTM_INST; \
- case 29: \
- goto VPOP_INST; \
- case 30: \
- goto VLDR_INST; \
- case 31: \
- goto VLDM_INST; \
- case 32: \
- goto SRS_INST; \
- case 33: \
- goto RFE_INST; \
- case 34: \
- goto BKPT_INST; \
- case 35: \
- goto BLX_INST; \
- case 36: \
- goto CPS_INST; \
- case 37: \
- goto PLD_INST; \
- case 38: \
- goto SETEND_INST; \
- case 39: \
- goto CLREX_INST; \
- case 40: \
- goto REV16_INST; \
- case 41: \
- goto USAD8_INST; \
- case 42: \
- goto SXTB_INST; \
- case 43: \
- goto UXTB_INST; \
- case 44: \
- goto SXTH_INST; \
- case 45: \
- goto SXTB16_INST; \
- case 46: \
- goto UXTH_INST; \
- case 47: \
- goto UXTB16_INST; \
- case 48: \
- goto CPY_INST; \
- case 49: \
- goto UXTAB_INST; \
- case 50: \
- goto SSUB8_INST; \
- case 51: \
- goto SHSUB8_INST; \
- case 52: \
- goto SSUBADDX_INST; \
- case 53: \
- goto STREX_INST; \
- case 54: \
- goto STREXB_INST; \
- case 55: \
- goto SWP_INST; \
- case 56: \
- goto SWPB_INST; \
- case 57: \
- goto SSUB16_INST; \
- case 58: \
- goto SSAT16_INST; \
- case 59: \
- goto SHSUBADDX_INST; \
- case 60: \
- goto QSUBADDX_INST; \
- case 61: \
- goto SHADDSUBX_INST; \
- case 62: \
- goto SHADD8_INST; \
- case 63: \
- goto SHADD16_INST; \
- case 64: \
- goto SEL_INST; \
- case 65: \
- goto SADDSUBX_INST; \
- case 66: \
- goto SADD8_INST; \
- case 67: \
- goto SADD16_INST; \
- case 68: \
- goto SHSUB16_INST; \
- case 69: \
- goto UMAAL_INST; \
- case 70: \
- goto UXTAB16_INST; \
- case 71: \
- goto USUBADDX_INST; \
- case 72: \
- goto USUB8_INST; \
- case 73: \
- goto USUB16_INST; \
- case 74: \
- goto USAT16_INST; \
- case 75: \
- goto USADA8_INST; \
- case 76: \
- goto UQSUBADDX_INST; \
- case 77: \
- goto UQSUB8_INST; \
- case 78: \
- goto UQSUB16_INST; \
- case 79: \
- goto UQADDSUBX_INST; \
- case 80: \
- goto UQADD8_INST; \
- case 81: \
- goto UQADD16_INST; \
- case 82: \
- goto SXTAB_INST; \
- case 83: \
- goto UHSUBADDX_INST; \
- case 84: \
- goto UHSUB8_INST; \
- case 85: \
- goto UHSUB16_INST; \
- case 86: \
- goto UHADDSUBX_INST; \
- case 87: \
- goto UHADD8_INST; \
- case 88: \
- goto UHADD16_INST; \
- case 89: \
- goto UADDSUBX_INST; \
- case 90: \
- goto UADD8_INST; \
- case 91: \
- goto UADD16_INST; \
- case 92: \
- goto SXTAH_INST; \
- case 93: \
- goto SXTAB16_INST; \
- case 94: \
- goto QADD8_INST; \
- case 95: \
- goto BXJ_INST; \
- case 96: \
- goto CLZ_INST; \
- case 97: \
- goto UXTAH_INST; \
- case 98: \
- goto BX_INST; \
- case 99: \
- goto REV_INST; \
- case 100: \
- goto BLX_INST; \
- case 101: \
- goto REVSH_INST; \
- case 102: \
- goto QADD_INST; \
- case 103: \
- goto QADD16_INST; \
- case 104: \
- goto QADDSUBX_INST; \
- case 105: \
- goto LDREX_INST; \
- case 106: \
- goto QDADD_INST; \
- case 107: \
- goto QDSUB_INST; \
- case 108: \
- goto QSUB_INST; \
- case 109: \
- goto LDREXB_INST; \
- case 110: \
- goto QSUB8_INST; \
- case 111: \
- goto QSUB16_INST; \
- case 112: \
- goto SMUAD_INST; \
- case 113: \
- goto SMMUL_INST; \
- case 114: \
- goto SMUSD_INST; \
- case 115: \
- goto SMLSD_INST; \
- case 116: \
- goto SMLSLD_INST; \
- case 117: \
- goto SMMLA_INST; \
- case 118: \
- goto SMMLS_INST; \
- case 119: \
- goto SMLALD_INST; \
- case 120: \
- goto SMLAD_INST; \
- case 121: \
- goto SMLAW_INST; \
- case 122: \
- goto SMULW_INST; \
- case 123: \
- goto PKHTB_INST; \
- case 124: \
- goto PKHBT_INST; \
- case 125: \
- goto SMUL_INST; \
- case 126: \
- goto SMLALXY_INST; \
- case 127: \
- goto SMLA_INST; \
- case 128: \
- goto MCRR_INST; \
- case 129: \
- goto MRRC_INST; \
- case 130: \
- goto CMP_INST; \
- case 131: \
- goto TST_INST; \
- case 132: \
- goto TEQ_INST; \
- case 133: \
- goto CMN_INST; \
- case 134: \
- goto SMULL_INST; \
- case 135: \
- goto UMULL_INST; \
- case 136: \
- goto UMLAL_INST; \
- case 137: \
- goto SMLAL_INST; \
- case 138: \
- goto MUL_INST; \
- case 139: \
- goto MLA_INST; \
- case 140: \
- goto SSAT_INST; \
- case 141: \
- goto USAT_INST; \
- case 142: \
- goto MRS_INST; \
- case 143: \
- goto MSR_INST; \
- case 144: \
- goto AND_INST; \
- case 145: \
- goto BIC_INST; \
- case 146: \
- goto LDM_INST; \
- case 147: \
- goto EOR_INST; \
- case 148: \
- goto ADD_INST; \
- case 149: \
- goto RSB_INST; \
- case 150: \
- goto RSC_INST; \
- case 151: \
- goto SBC_INST; \
- case 152: \
- goto ADC_INST; \
- case 153: \
- goto SUB_INST; \
- case 154: \
- goto ORR_INST; \
- case 155: \
- goto MVN_INST; \
- case 156: \
- goto MOV_INST; \
- case 157: \
- goto STM_INST; \
- case 158: \
- goto LDM_INST; \
- case 159: \
- goto LDRSH_INST; \
- case 160: \
- goto STM_INST; \
- case 161: \
- goto LDM_INST; \
- case 162: \
- goto LDRSB_INST; \
- case 163: \
- goto STRD_INST; \
- case 164: \
- goto LDRH_INST; \
- case 165: \
- goto STRH_INST; \
- case 166: \
- goto LDRD_INST; \
- case 167: \
- goto STRT_INST; \
- case 168: \
- goto STRBT_INST; \
- case 169: \
- goto LDRBT_INST; \
- case 170: \
- goto LDRT_INST; \
- case 171: \
- goto MRC_INST; \
- case 172: \
- goto MCR_INST; \
- case 173: \
- goto MSR_INST; \
- case 174: \
- goto MSR_INST; \
- case 175: \
- goto MSR_INST; \
- case 176: \
- goto MSR_INST; \
- case 177: \
- goto MSR_INST; \
- case 178: \
- goto LDRB_INST; \
- case 179: \
- goto STRB_INST; \
- case 180: \
- goto LDR_INST; \
- case 181: \
- goto LDRCOND_INST; \
- case 182: \
- goto STR_INST; \
- case 183: \
- goto CDP_INST; \
- case 184: \
- goto STC_INST; \
- case 185: \
- goto LDC_INST; \
- case 186: \
- goto LDREXD_INST; \
- case 187: \
- goto STREXD_INST; \
- case 188: \
- goto LDREXH_INST; \
- case 189: \
- goto STREXH_INST; \
- case 190: \
- goto NOP_INST; \
- case 191: \
- goto YIELD_INST; \
- case 192: \
- goto WFE_INST; \
- case 193: \
- goto WFI_INST; \
- case 194: \
- goto SEV_INST; \
- case 195: \
- goto SWI_INST; \
- case 196: \
- goto BBL_INST; \
- case 197: \
- goto B_2_THUMB; \
- case 198: \
- goto B_COND_THUMB; \
- case 199: \
- goto BL_1_THUMB; \
- case 200: \
- goto BL_2_THUMB; \
- case 201: \
- goto BLX_1_THUMB; \
- case 202: \
- goto DISPATCH; \
- case 203: \
- goto INIT_INST_LENGTH; \
- case 204: \
- goto END; \
- }
-#endif
-
-#define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
-#define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
-#define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
-
-#define SAVE_NZCVT \
- cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | (cpu->NFlag << 31) | (cpu->ZFlag << 30) | \
- (cpu->CFlag << 29) | (cpu->VFlag << 28) | (cpu->TFlag << 5)
-#define LOAD_NZCVT \
- cpu->NFlag = (cpu->Cpsr >> 31); \
- cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
- cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
- cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
- cpu->TFlag = (cpu->Cpsr >> 5) & 1;
-
-#define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
-#define PC (cpu->Reg[15])
-
-// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
-// to a clunky switch statement.
-#if defined __GNUC__ || defined __clang__
- void* InstLabel[] = {&&VMLA_INST,
- &&VMLS_INST,
- &&VNMLA_INST,
- &&VNMLS_INST,
- &&VNMUL_INST,
- &&VMUL_INST,
- &&VADD_INST,
- &&VSUB_INST,
- &&VDIV_INST,
- &&VMOVI_INST,
- &&VMOVR_INST,
- &&VABS_INST,
- &&VNEG_INST,
- &&VSQRT_INST,
- &&VCMP_INST,
- &&VCMP2_INST,
- &&VCVTBDS_INST,
- &&VCVTBFF_INST,
- &&VCVTBFI_INST,
- &&VMOVBRS_INST,
- &&VMSR_INST,
- &&VMOVBRC_INST,
- &&VMRS_INST,
- &&VMOVBCR_INST,
- &&VMOVBRRSS_INST,
- &&VMOVBRRD_INST,
- &&VSTR_INST,
- &&VPUSH_INST,
- &&VSTM_INST,
- &&VPOP_INST,
- &&VLDR_INST,
- &&VLDM_INST,
-
- &&SRS_INST,
- &&RFE_INST,
- &&BKPT_INST,
- &&BLX_INST,
- &&CPS_INST,
- &&PLD_INST,
- &&SETEND_INST,
- &&CLREX_INST,
- &&REV16_INST,
- &&USAD8_INST,
- &&SXTB_INST,
- &&UXTB_INST,
- &&SXTH_INST,
- &&SXTB16_INST,
- &&UXTH_INST,
- &&UXTB16_INST,
- &&CPY_INST,
- &&UXTAB_INST,
- &&SSUB8_INST,
- &&SHSUB8_INST,
- &&SSUBADDX_INST,
- &&STREX_INST,
- &&STREXB_INST,
- &&SWP_INST,
- &&SWPB_INST,
- &&SSUB16_INST,
- &&SSAT16_INST,
- &&SHSUBADDX_INST,
- &&QSUBADDX_INST,
- &&SHADDSUBX_INST,
- &&SHADD8_INST,
- &&SHADD16_INST,
- &&SEL_INST,
- &&SADDSUBX_INST,
- &&SADD8_INST,
- &&SADD16_INST,
- &&SHSUB16_INST,
- &&UMAAL_INST,
- &&UXTAB16_INST,
- &&USUBADDX_INST,
- &&USUB8_INST,
- &&USUB16_INST,
- &&USAT16_INST,
- &&USADA8_INST,
- &&UQSUBADDX_INST,
- &&UQSUB8_INST,
- &&UQSUB16_INST,
- &&UQADDSUBX_INST,
- &&UQADD8_INST,
- &&UQADD16_INST,
- &&SXTAB_INST,
- &&UHSUBADDX_INST,
- &&UHSUB8_INST,
- &&UHSUB16_INST,
- &&UHADDSUBX_INST,
- &&UHADD8_INST,
- &&UHADD16_INST,
- &&UADDSUBX_INST,
- &&UADD8_INST,
- &&UADD16_INST,
- &&SXTAH_INST,
- &&SXTAB16_INST,
- &&QADD8_INST,
- &&BXJ_INST,
- &&CLZ_INST,
- &&UXTAH_INST,
- &&BX_INST,
- &&REV_INST,
- &&BLX_INST,
- &&REVSH_INST,
- &&QADD_INST,
- &&QADD16_INST,
- &&QADDSUBX_INST,
- &&LDREX_INST,
- &&QDADD_INST,
- &&QDSUB_INST,
- &&QSUB_INST,
- &&LDREXB_INST,
- &&QSUB8_INST,
- &&QSUB16_INST,
- &&SMUAD_INST,
- &&SMMUL_INST,
- &&SMUSD_INST,
- &&SMLSD_INST,
- &&SMLSLD_INST,
- &&SMMLA_INST,
- &&SMMLS_INST,
- &&SMLALD_INST,
- &&SMLAD_INST,
- &&SMLAW_INST,
- &&SMULW_INST,
- &&PKHTB_INST,
- &&PKHBT_INST,
- &&SMUL_INST,
- &&SMLALXY_INST,
- &&SMLA_INST,
- &&MCRR_INST,
- &&MRRC_INST,
- &&CMP_INST,
- &&TST_INST,
- &&TEQ_INST,
- &&CMN_INST,
- &&SMULL_INST,
- &&UMULL_INST,
- &&UMLAL_INST,
- &&SMLAL_INST,
- &&MUL_INST,
- &&MLA_INST,
- &&SSAT_INST,
- &&USAT_INST,
- &&MRS_INST,
- &&MSR_INST,
- &&AND_INST,
- &&BIC_INST,
- &&LDM_INST,
- &&EOR_INST,
- &&ADD_INST,
- &&RSB_INST,
- &&RSC_INST,
- &&SBC_INST,
- &&ADC_INST,
- &&SUB_INST,
- &&ORR_INST,
- &&MVN_INST,
- &&MOV_INST,
- &&STM_INST,
- &&LDM_INST,
- &&LDRSH_INST,
- &&STM_INST,
- &&LDM_INST,
- &&LDRSB_INST,
- &&STRD_INST,
- &&LDRH_INST,
- &&STRH_INST,
- &&LDRD_INST,
- &&STRT_INST,
- &&STRBT_INST,
- &&LDRBT_INST,
- &&LDRT_INST,
- &&MRC_INST,
- &&MCR_INST,
- &&MSR_INST,
- &&MSR_INST,
- &&MSR_INST,
- &&MSR_INST,
- &&MSR_INST,
- &&LDRB_INST,
- &&STRB_INST,
- &&LDR_INST,
- &&LDRCOND_INST,
- &&STR_INST,
- &&CDP_INST,
- &&STC_INST,
- &&LDC_INST,
- &&LDREXD_INST,
- &&STREXD_INST,
- &&LDREXH_INST,
- &&STREXH_INST,
- &&NOP_INST,
- &&YIELD_INST,
- &&WFE_INST,
- &&WFI_INST,
- &&SEV_INST,
- &&SWI_INST,
- &&BBL_INST,
- &&B_2_THUMB,
- &&B_COND_THUMB,
- &&BL_1_THUMB,
- &&BL_2_THUMB,
- &&BLX_1_THUMB,
- &&DISPATCH,
- &&INIT_INST_LENGTH,
- &&END};
-#endif
- arm_inst* inst_base;
- unsigned int addr;
- unsigned int num_instrs = 0;
-
- std::size_t ptr;
-
- LOAD_NZCVT;
-DISPATCH : {
- if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
- goto END;
- }
- }
-
- if (cpu->TFlag)
- cpu->Reg[15] &= 0xfffffffe;
- else
- cpu->Reg[15] &= 0xfffffffc;
-
- // Find the cached instruction cream, otherwise translate it...
- auto itr = cpu->instruction_cache.find(cpu->Reg[15]);
- if (itr != cpu->instruction_cache.end()) {
- ptr = itr->second;
- } else if (cpu->NumInstrsToExecute != 1) {
- if (InterpreterTranslateBlock(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- } else {
- if (InterpreterTranslateSingle(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- }
-
- // Find breakpoint if one exists within the block
- if (GDBStub::IsConnected()) {
- breakpoint_data =
- GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute);
- }
-
- inst_base = (arm_inst*)&trans_cache_buf[ptr];
- GOTO_NEXT_INST;
-}
-ADC_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- adc_inst* const inst_cream = (adc_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(adc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(adc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-ADD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- add_inst* const inst_cream = (add_inst*)inst_base->component;
-
- u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(add_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(add_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-AND_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- and_inst* const inst_cream = (and_inst*)inst_base->component;
-
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
-
- if (inst_cream->Rn == 15)
- lop += 2 * cpu->GetInstructionSize();
-
- RD = lop & rop;
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(and_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(and_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-BBL_INST : {
- if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
- bbl_inst* inst_cream = (bbl_inst*)inst_base->component;
- if (inst_cream->L) {
- LINK_RTN_ADDR;
- }
- SET_PC;
- INC_PC(sizeof(bbl_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bbl_inst));
- goto DISPATCH;
-}
-BIC_INST : {
- bic_inst* inst_cream = (bic_inst*)inst_base->component;
- if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
- u32 lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * cpu->GetInstructionSize();
- }
- u32 rop = SHIFTER_OPERAND;
- RD = lop & (~rop);
- if ((inst_cream->S) && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(bic_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bic_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-BKPT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
- LOG_DEBUG(Core_ARM, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bkpt_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-BLX_INST : {
- blx_inst* inst_cream = (blx_inst*)inst_base->component;
- if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
- unsigned int inst = inst_cream->inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- const u32 jump_address = cpu->Reg[inst_cream->val.Rm];
- cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
- if (cpu->TFlag)
- cpu->Reg[14] |= 0x1;
- cpu->Reg[15] = jump_address & 0xfffffffe;
- cpu->TFlag = jump_address & 0x1;
- } else {
- cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
- cpu->TFlag = 0x1;
- int signed_int = inst_cream->val.signed_immed_24;
- signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
- signed_int = signed_int << 2;
- cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
- }
- INC_PC(sizeof(blx_inst));
- goto DISPATCH;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(blx_inst));
- goto DISPATCH;
-}
-
-BX_INST:
-BXJ_INST : {
- // Note that only the 'fail' case of BXJ is emulated. This is because
- // the facilities for Jazelle emulation are not implemented.
- //
- // According to the ARM documentation on BXJ, if setting the J bit in the APSR
- // fails, then BXJ functions identically like a regular BX instruction.
- //
- // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
-
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- bx_inst* const inst_cream = (bx_inst*)inst_base->component;
-
- u32 address = RM;
-
- if (inst_cream->Rm == 15)
- address += 2 * cpu->GetInstructionSize();
-
- cpu->TFlag = address & 1;
- cpu->Reg[15] = address & 0xfffffffe;
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
-}
-
-CDP_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- // Undefined instruction here
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cdp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-CLREX_INST : {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(clrex_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-CLZ_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- clz_inst* inst_cream = (clz_inst*)inst_base->component;
- RD = clz(RM);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(clz_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-CMN_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
-
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cmn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-CMP_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- cmp_inst* const inst_cream = (cmp_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
-
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cmp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-CPS_INST : {
- cps_inst* inst_cream = (cps_inst*)inst_base->component;
- u32 aif_val = 0;
- u32 aif_mask = 0;
- if (cpu->InAPrivilegedMode()) {
- if (inst_cream->imod1) {
- if (inst_cream->A) {
- aif_val |= (inst_cream->imod0 << 8);
- aif_mask |= 1 << 8;
- }
- if (inst_cream->I) {
- aif_val |= (inst_cream->imod0 << 7);
- aif_mask |= 1 << 7;
- }
- if (inst_cream->F) {
- aif_val |= (inst_cream->imod0 << 6);
- aif_mask |= 1 << 6;
- }
- aif_mask = ~aif_mask;
- cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
- }
- if (inst_cream->mmod) {
- cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
- cpu->ChangePrivilegeMode(inst_cream->mode);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cps_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-CPY_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
-
- RD = SHIFTER_OPERAND;
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-EOR_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- eor_inst* inst_cream = (eor_inst*)inst_base->component;
-
- u32 lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * cpu->GetInstructionSize();
- }
- u32 rop = SHIFTER_OPERAND;
- RD = lop ^ rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(eor_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(eor_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDC_INST : {
- // Instruction not implemented
- // LOG_CRITICAL(Core_ARM, "unimplemented instruction");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDM_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int inst = inst_cream->inst;
- if (BIT(inst, 22) && !BIT(inst, 15)) {
- for (int i = 0; i < 13; i++) {
- if (BIT(inst, i)) {
- cpu->Reg[i] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- }
- if (BIT(inst, 13)) {
- if (cpu->Mode == USER32MODE)
- cpu->Reg[13] = cpu->ReadMemory32(addr);
- else
- cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
-
- addr += 4;
- }
- if (BIT(inst, 14)) {
- if (cpu->Mode == USER32MODE)
- cpu->Reg[14] = cpu->ReadMemory32(addr);
- else
- cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
-
- addr += 4;
- }
- } else if (!BIT(inst, 22)) {
- for (int i = 0; i < 16; i++) {
- if (BIT(inst, i)) {
- unsigned int ret = cpu->ReadMemory32(addr);
-
- // For armv5t, should enter thumb when bits[0] is non-zero.
- if (i == 15) {
- cpu->TFlag = ret & 0x1;
- ret &= 0xFFFFFFFE;
- }
-
- cpu->Reg[i] = ret;
- addr += 4;
- }
- }
- } else if (BIT(inst, 22) && BIT(inst, 15)) {
- for (int i = 0; i < 15; i++) {
- if (BIT(inst, i)) {
- cpu->Reg[i] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- }
-
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
-
- cpu->Reg[15] = cpu->ReadMemory32(addr);
- }
-
- if (BIT(inst, 15)) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SXTH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxth_inst* inst_cream = (sxth_inst*)inst_base->component;
-
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 15)) {
- operand2 |= 0xffff0000;
- } else {
- operand2 &= 0xffff;
- }
- RD = operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDR_INST : {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
-
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- // For armv5t, should enter thumb when bits[0] is non-zero.
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRCOND_INST : {
- if (CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
-
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- // For armv5t, should enter thumb when bits[0] is non-zero.
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-UXTH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
- RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-UXTAH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
-
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRBT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- const u32 dest_index = BITS(inst_cream->inst, 12, 15);
- const u32 previous_mode = cpu->Mode;
-
- cpu->ChangePrivilegeMode(USER32MODE);
- const u8 value = cpu->ReadMemory8(addr);
- cpu->ChangePrivilegeMode(previous_mode);
-
- cpu->Reg[dest_index] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 ||
- // addr[2] == 0)
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
- // wouldn't do this as a single read.
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
-
- // No dispatch since this operation should not modify R15
- }
- cpu->Reg[15] += 4;
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-LDREX_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
-
- cpu->SetExclusiveMemoryAddress(read_addr);
-
- RD = cpu->ReadMemory32(read_addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDREXB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
-
- cpu->SetExclusiveMemoryAddress(read_addr);
-
- RD = cpu->ReadMemory8(read_addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDREXH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
-
- cpu->SetExclusiveMemoryAddress(read_addr);
-
- RD = cpu->ReadMemory16(read_addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDREXD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
-
- cpu->SetExclusiveMemoryAddress(read_addr);
-
- RD = cpu->ReadMemory32(read_addr);
- RD2 = cpu->ReadMemory32(read_addr + 4);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRSB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->ReadMemory8(addr);
- if (BIT(value, 7)) {
- value |= 0xffffff00;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRSH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->ReadMemory16(addr);
- if (BIT(value, 15)) {
- value |= 0xffff0000;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-LDRT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- const u32 dest_index = BITS(inst_cream->inst, 12, 15);
- const u32 previous_mode = cpu->Mode;
-
- cpu->ChangePrivilegeMode(USER32MODE);
- const u32 value = cpu->ReadMemory32(addr);
- cpu->ChangePrivilegeMode(previous_mode);
-
- cpu->Reg[dest_index] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-MCR_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mcr_inst* inst_cream = (mcr_inst*)inst_base->component;
-
- unsigned int inst = inst_cream->inst;
- if (inst_cream->Rd == 15) {
- DEBUG_MSG;
- } else {
- if (inst_cream->cp_num == 15)
- cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-MCRR_INST : {
- // Stubbed, as the MPCore doesn't have any registers that are accessible
- // through this instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
-
- LOG_ERROR(Core_ARM, "MCRR executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
- inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt,
- inst_cream->rt2);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcrr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-MLA_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mla_inst* inst_cream = (mla_inst*)inst_base->component;
-
- u64 rm = RM;
- u64 rs = RS;
- u64 rn = RN;
-
- RD = static_cast<u32>((rm * rs + rn) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-MOV_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
-
- RD = SHIFTER_OPERAND;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-MRC_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
-
- if (inst_cream->cp_num == 15) {
- const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
-
- if (inst_cream->Rd == 15) {
- cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000);
- LOAD_NZCVT;
- } else {
- RD = value;
- }
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mrc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-MRRC_INST : {
- // Stubbed, as the MPCore doesn't have any registers that are accessible
- // through this instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
-
- LOG_ERROR(Core_ARM, "MRRC executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
- inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt,
- inst_cream->rt2);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcrr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-MRS_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mrs_inst* inst_cream = (mrs_inst*)inst_base->component;
-
- if (inst_cream->R) {
- RD = cpu->Spsr_copy;
- } else {
- SAVE_NZCVT;
- RD = cpu->Cpsr;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mrs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-MSR_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- msr_inst* inst_cream = (msr_inst*)inst_base->component;
- const u32 UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
- unsigned int inst = inst_cream->inst;
- unsigned int operand;
-
- if (BIT(inst, 25)) {
- int rot_imm = BITS(inst, 8, 11) * 2;
- operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
- } else {
- operand = cpu->Reg[BITS(inst, 0, 3)];
- }
- u32 byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) |
- (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
- u32 mask = 0;
- if (!inst_cream->R) {
- if (cpu->InAPrivilegedMode()) {
- if ((operand & StateMask) != 0) {
- /// UNPREDICTABLE
- DEBUG_MSG;
- } else
- mask = byte_mask & (UserMask | PrivMask);
- } else {
- mask = byte_mask & UserMask;
- }
- SAVE_NZCVT;
-
- cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- } else {
- if (CurrentModeHasSPSR) {
- mask = byte_mask & (UserMask | PrivMask | StateMask);
- cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
- }
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(msr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-MUL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mul_inst* inst_cream = (mul_inst*)inst_base->component;
-
- u64 rm = RM;
- u64 rs = RS;
- RD = static_cast<u32>((rm * rs) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-MVN_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mvn_inst* const inst_cream = (mvn_inst*)inst_base->component;
-
- RD = ~SHIFTER_OPERAND;
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mvn_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mvn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-ORR_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- orr_inst* const inst_cream = (orr_inst*)inst_base->component;
-
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
-
- if (inst_cream->Rn == 15)
- lop += 2 * cpu->GetInstructionSize();
-
- RD = lop | rop;
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(orr_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(orr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-NOP_INST : {
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-PKHBT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
- RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-PKHTB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
- int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
- RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-PLD_INST : {
- // Not implemented. PLD is a hint instruction, so it's optional.
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pld_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-QADD_INST:
-QDADD_INST:
-QDSUB_INST:
-QSUB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op1 = inst_cream->op1;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- u32 result = 0;
-
- // QADD
- if (op1 == 0x00) {
- result = rm_val + rn_val;
-
- if (AddOverflow(rm_val, rn_val, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QSUB
- else if (op1 == 0x01) {
- result = rm_val - rn_val;
-
- if (SubOverflow(rm_val, rn_val, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QDADD
- else if (op1 == 0x02) {
- u32 mul = (rn_val * 2);
-
- if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
- mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
-
- result = mul + rm_val;
-
- if (AddOverflow(rm_val, mul, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QDSUB
- else if (op1 == 0x03) {
- u32 mul = (rn_val * 2);
-
- if (AddOverflow(rn_val, rn_val, mul)) {
- mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
-
- result = rm_val - mul;
-
- if (SubOverflow(rm_val, mul, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
-
- RD = result;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-QADD8_INST:
-QADD16_INST:
-QADDSUBX_INST:
-QSUB8_INST:
-QSUB16_INST:
-QSUBADDX_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u16 rm_lo = (RM & 0xFFFF);
- const u16 rm_hi = ((RM >> 16) & 0xFFFF);
- const u16 rn_lo = (RN & 0xFFFF);
- const u16 rn_hi = ((RN >> 16) & 0xFFFF);
- const u8 op2 = inst_cream->op2;
-
- u16 lo_result = 0;
- u16 hi_result = 0;
-
- // QADD16
- if (op2 == 0x00) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
- }
- // QASX
- else if (op2 == 0x01) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
- }
- // QSAX
- else if (op2 == 0x02) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
- }
- // QSUB16
- else if (op2 == 0x03) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
- }
- // QADD8
- else if (op2 == 0x04) {
- lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
- }
- // QSUB8
- else if (op2 == 0x07) {
- lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
- }
-
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-REV_INST:
-REV16_INST:
-REVSH_INST : {
-
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- rev_inst* const inst_cream = (rev_inst*)inst_base->component;
-
- const u8 op1 = inst_cream->op1;
- const u8 op2 = inst_cream->op2;
-
- // REV
- if (op1 == 0x03 && op2 == 0x01) {
- RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) |
- ((RM >> 24) & 0xFF);
- }
- // REV16
- else if (op1 == 0x03 && op2 == 0x05) {
- RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) |
- ((RM & 0xFF000000) >> 8);
- }
- // REVSH
- else if (op1 == 0x07 && op2 == 0x05) {
- RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
- if (RD & 0x8000)
- RD |= 0xffff0000;
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rev_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-RFE_INST : {
- // RFE is unconditional
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
-
- u32 address = 0;
- inst_cream->get_addr(cpu, inst_cream->inst, address);
-
- cpu->Cpsr = cpu->ReadMemory32(address);
- cpu->Reg[15] = cpu->ReadMemory32(address + 4);
-
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
-}
-
-RSB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- rsb_inst* const inst_cream = (rsb_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsb_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rsb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-RSC_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rsc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SADD8_INST:
-SSUB8_INST:
-SADD16_INST:
-SADDSUBX_INST:
-SSUBADDX_INST:
-SSUB16_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
-
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- const s16 rn_lo = (RN & 0xFFFF);
- const s16 rn_hi = ((RN >> 16) & 0xFFFF);
- const s16 rm_lo = (RM & 0xFFFF);
- const s16 rm_hi = ((RM >> 16) & 0xFFFF);
-
- s32 lo_result = 0;
- s32 hi_result = 0;
-
- // SADD16
- if (inst_cream->op2 == 0x00) {
- lo_result = (rn_lo + rm_lo);
- hi_result = (rn_hi + rm_hi);
- }
- // SASX
- else if (op2 == 0x01) {
- lo_result = (rn_lo - rm_hi);
- hi_result = (rn_hi + rm_lo);
- }
- // SSAX
- else if (op2 == 0x02) {
- lo_result = (rn_lo + rm_hi);
- hi_result = (rn_hi - rm_lo);
- }
- // SSUB16
- else if (op2 == 0x03) {
- lo_result = (rn_lo - rm_lo);
- hi_result = (rn_hi - rm_hi);
- }
-
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
-
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
-
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- } else if (op2 == 0x04 || op2 == 0x07) {
- s32 lo_val1, lo_val2;
- s32 hi_val1, hi_val2;
-
- // SADD8
- if (op2 == 0x04) {
- lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
- lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
- hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
- hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
- }
- // SSUB8
- else {
- lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
- lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
- hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
- hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
- }
-
- RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) |
- ((hi_val2 & 0xFF) << 24));
-
- if (lo_val1 >= 0)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
-
- if (lo_val2 >= 0)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
-
- if (hi_val1 >= 0)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
-
- if (hi_val2 >= 0)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SBC_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sbc_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sbc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SEL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u32 to = RM;
- const u32 from = RN;
- const u32 cpsr = cpu->Cpsr;
-
- u32 result;
- if (cpsr & (1 << 16))
- result = from & 0xff;
- else
- result = to & 0xff;
-
- if (cpsr & (1 << 17))
- result |= from & 0x0000ff00;
- else
- result |= to & 0x0000ff00;
-
- if (cpsr & (1 << 18))
- result |= from & 0x00ff0000;
- else
- result |= to & 0x00ff0000;
-
- if (cpsr & (1 << 19))
- result |= from & 0xff000000;
- else
- result |= to & 0xff000000;
-
- RD = result;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SETEND_INST : {
- // SETEND is unconditional
- setend_inst* const inst_cream = (setend_inst*)inst_base->component;
- const bool big_endian = (inst_cream->set_bigend == 1);
-
- if (big_endian)
- cpu->Cpsr |= (1 << 9);
- else
- cpu->Cpsr &= ~(1 << 9);
-
- LOG_WARNING(Core_ARM, "SETEND %s executed", big_endian ? "BE" : "LE");
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(setend_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SEV_INST : {
- // Stubbed, as SEV is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM, "SEV executed.");
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SHADD8_INST:
-SHADD16_INST:
-SHADDSUBX_INST:
-SHSUB8_INST:
-SHSUB16_INST:
-SHSUBADDX_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- s32 lo_result = 0;
- s32 hi_result = 0;
-
- // SHADD16
- if (op2 == 0x00) {
- lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- }
- // SHASX
- else if (op2 == 0x01) {
- lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
- }
- // SHSAX
- else if (op2 == 0x02) {
- lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
- }
- // SHSUB16
- else if (op2 == 0x03) {
- lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- }
-
- RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
- } else if (op2 == 0x04 || op2 == 0x07) {
- s16 lo_val1, lo_val2;
- s16 hi_val1, hi_val2;
-
- // SHADD8
- if (op2 == 0x04) {
- lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
- lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
-
- hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
- hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
- }
- // SHSUB8
- else {
- lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
- lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
-
- hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
- hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
- }
-
- RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) |
- ((hi_val2 & 0xFF) << 24);
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMLA_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smla_inst* inst_cream = (smla_inst*)inst_base->component;
- s32 operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
-
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
-
- u32 product = operand1 * operand2;
- u32 result = product + RN;
- if (AddOverflow(product, RN, result))
- cpu->Cpsr |= (1 << 27);
- RD = result;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMLAD_INST:
-SMLSD_INST:
-SMUAD_INST:
-SMUSD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
-
- u32 rm_val = cpu->Reg[inst_cream->Rm];
- const u32 rn_val = cpu->Reg[inst_cream->Rn];
-
- if (inst_cream->m)
- rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
-
- const s16 rm_lo = (rm_val & 0xFFFF);
- const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
- const s16 rn_lo = (rn_val & 0xFFFF);
- const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
-
- const u32 product1 = (rn_lo * rm_lo);
- const u32 product2 = (rn_hi * rm_hi);
-
- // SMUAD and SMLAD
- if (BIT(op2, 1) == 0) {
- u32 rd_val = (product1 + product2);
-
- if (inst_cream->Ra != 15) {
- rd_val += cpu->Reg[inst_cream->Ra];
-
- if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
- cpu->Cpsr |= (1 << 27);
- }
-
- RD = rd_val;
-
- if (ARMul_AddOverflowQ(product1, product2))
- cpu->Cpsr |= (1 << 27);
- }
- // SMUSD and SMLSD
- else {
- u32 rd_val = (product1 - product2);
-
- if (inst_cream->Ra != 15) {
- rd_val += cpu->Reg[inst_cream->Ra];
-
- if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
- cpu->Cpsr |= (1 << 27);
- }
-
- RD = rd_val;
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMLAL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
- long long int rm = RM;
- long long int rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- long long int rst = rm * rs;
- long long int rdhi32 = RDHI;
- long long int hilo = (rdhi32 << 32) + RDLO;
- rst += hilo;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMLALXY_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
-
- u64 operand1 = RN;
- u64 operand2 = RM;
-
- if (inst_cream->x != 0)
- operand1 >>= 16;
- if (inst_cream->y != 0)
- operand2 >>= 16;
- operand1 &= 0xFFFF;
- if (operand1 & 0x8000)
- operand1 -= 65536;
- operand2 &= 0xFFFF;
- if (operand2 & 0x8000)
- operand2 -= 65536;
-
- u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2);
- RDLO = (dest & 0xFFFFFFFF);
- RDHI = ((dest >> 32) & 0xFFFFFFFF);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlalxy_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMLAW_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u32 ra_val = cpu->Reg[inst_cream->Ra];
- const bool high = (inst_cream->m == 1);
-
- const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
- const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
-
- RD = BITS(result, 16, 47);
-
- if ((result >> 16) != (s32)RD)
- cpu->Cpsr |= (1 << 27);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMLALD_INST:
-SMLSLD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
-
- const bool do_swap = (inst_cream->swap == 1);
- const u32 rdlo_val = RDLO;
- const u32 rdhi_val = RDHI;
- const u32 rn_val = RN;
- u32 rm_val = RM;
-
- if (do_swap)
- rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
-
- const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
- const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
- s64 result;
-
- // SMLALD
- if (BIT(inst_cream->op2, 1) == 0) {
- result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
- }
- // SMLSLD
- else {
- result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
- }
-
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlald_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMMLA_INST:
-SMMLS_INST:
-SMMUL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const bool do_round = (inst_cream->m == 1);
-
- // Assume SMMUL by default.
- s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
-
- if (inst_cream->Ra != 15) {
- const u32 ra_val = cpu->Reg[inst_cream->Ra];
-
- // SMMLA, otherwise SMMLS
- if (BIT(inst_cream->op2, 1) == 0)
- result += ((s64)ra_val << 32);
- else
- result = ((s64)ra_val << 32) - result;
- }
-
- if (do_round)
- result += 0x80000000;
-
- RD = ((result >> 32) & 0xFFFFFFFF);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMUL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smul_inst* inst_cream = (smul_inst*)inst_base->component;
- u32 operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
-
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
- RD = operand1 * operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SMULL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
- s64 rm = RM;
- s64 rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- s64 rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SMULW_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF);
-
- s64 result = (s64)rm * (s64)(s32)RN;
- RD = BITS(result, 16, 47);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SRS_INST : {
- // SRS is unconditional
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
-
- u32 address = 0;
- inst_cream->get_addr(cpu, inst_cream->inst, address);
-
- cpu->WriteMemory32(address + 0, cpu->Reg[14]);
- cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SSAT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
-
- u8 shift_type = inst_cream->shift_type;
- u8 shift_amount = inst_cream->imm5;
- u32 rn_val = RN;
-
- // 32-bit ASR is encoded as an amount of 0.
- if (shift_type == 1 && shift_amount == 0)
- shift_amount = 31;
-
- if (shift_type == 0)
- rn_val <<= shift_amount;
- else if (shift_type == 1)
- rn_val = ((s32)rn_val >> shift_amount);
-
- bool saturated = false;
- rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
-
- if (saturated)
- cpu->Cpsr |= (1 << 27);
-
- RD = rn_val;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SSAT16_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- const u8 saturate_to = inst_cream->sat_imm;
-
- bool sat1 = false;
- bool sat2 = false;
-
- RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
- ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
-
- if (sat1 || sat2)
- cpu->Cpsr |= (1 << 27);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-STC_INST : {
- // Instruction not implemented
- // LOG_CRITICAL(Core_ARM, "unimplemented instruction");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(stc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STM_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- unsigned int inst = inst_cream->inst;
-
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int old_RN = cpu->Reg[Rn];
-
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- if (BIT(inst_cream->inst, 22) == 1) {
- for (int i = 0; i < 13; i++) {
- if (BIT(inst_cream->inst, i)) {
- cpu->WriteMemory32(addr, cpu->Reg[i]);
- addr += 4;
- }
- }
- if (BIT(inst_cream->inst, 13)) {
- if (cpu->Mode == USER32MODE)
- cpu->WriteMemory32(addr, cpu->Reg[13]);
- else
- cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
-
- addr += 4;
- }
- if (BIT(inst_cream->inst, 14)) {
- if (cpu->Mode == USER32MODE)
- cpu->WriteMemory32(addr, cpu->Reg[14]);
- else
- cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
-
- addr += 4;
- }
- if (BIT(inst_cream->inst, 15)) {
- cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
- }
- } else {
- for (int i = 0; i < 15; i++) {
- if (BIT(inst_cream->inst, i)) {
- if (i == Rn)
- cpu->WriteMemory32(addr, old_RN);
- else
- cpu->WriteMemory32(addr, cpu->Reg[i]);
-
- addr += 4;
- }
- }
-
- // Check PC reg
- if (BIT(inst_cream->inst, 15)) {
- cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
- }
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SXTB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
-
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 7)) {
- operand2 |= 0xffffff00;
- } else {
- operand2 &= 0xff;
- }
- RD = operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STR_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int reg = BITS(inst_cream->inst, 12, 15);
- unsigned int value = cpu->Reg[reg];
-
- if (reg == 15)
- value += 2 * cpu->GetInstructionSize();
-
- cpu->WriteMemory32(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-UXTB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
- RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-UXTAB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component;
-
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STRB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- cpu->WriteMemory8(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STRBT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- const u32 previous_mode = cpu->Mode;
- const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
-
- cpu->ChangePrivilegeMode(USER32MODE);
- cpu->WriteMemory8(addr, value);
- cpu->ChangePrivilegeMode(previous_mode);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STRD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- // The 3DS doesn't have the Large Physical Access Extension (LPAE)
- // so STRD wouldn't store these as a single write.
- cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
- cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STREX_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory32(write_addr, RM);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STREXB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STREXD_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
-
- const u32 rt = cpu->Reg[inst_cream->Rm + 0];
- const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
- u64 value;
-
- if (cpu->InBigEndianMode())
- value = (((u64)rt << 32) | rt2);
- else
- value = (((u64)rt2 << 32) | rt);
-
- cpu->WriteMemory64(write_addr, value);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STREXH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory16(write_addr, RM);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STRH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
- cpu->WriteMemory16(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-STRT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- const u32 previous_mode = cpu->Mode;
- const u32 rt_index = BITS(inst_cream->inst, 12, 15);
-
- u32 value = cpu->Reg[rt_index];
- if (rt_index == 15)
- value += 2 * cpu->GetInstructionSize();
-
- cpu->ChangePrivilegeMode(USER32MODE);
- cpu->WriteMemory32(addr, value);
- cpu->ChangePrivilegeMode(previous_mode);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SUB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sub_inst* const inst_cream = (sub_inst*)inst_base->component;
-
- u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sub_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sub_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SWI_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- swi_inst* const inst_cream = (swi_inst*)inst_base->component;
- SVC::CallSVC(inst_cream->num & 0xFFFF);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swi_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SWP_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
-
- addr = RN;
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->WriteMemory32(addr, RM);
-
- RD = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SWPB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
- addr = RN;
- unsigned int value = cpu->ReadMemory8(addr);
- cpu->WriteMemory8(addr, (RM & 0xFF));
- RD = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-SXTAB_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component;
-
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
-
- // Sign extend for byte
- operand2 = (0x80 & operand2) ? (0xFFFFFF00 | operand2) : operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SXTAB16_INST:
-SXTB16_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
-
- const u8 rotation = inst_cream->rotate * 8;
- u32 rm_val = RM;
- u32 rn_val = RN;
-
- if (rotation)
- rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
-
- // SXTB16
- if (inst_cream->Rn == 15) {
- u32 lo = (u32)(s8)rm_val;
- u32 hi = (u32)(s8)(rm_val >> 16);
- RD = (lo & 0xFFFF) | (hi << 16);
- }
- // SXTAB16
- else {
- u32 lo = rn_val + (u32)(s8)(rm_val & 0xFF);
- u32 hi = (rn_val >> 16) + (u32)(s8)((rm_val >> 16) & 0xFF);
- RD = (lo & 0xFFFF) | (hi << 16);
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-SXTAH_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component;
-
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- // Sign extend for half
- operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-TEQ_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- teq_inst* const inst_cream = (teq_inst*)inst_base->component;
-
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
-
- if (inst_cream->Rn == 15)
- lop += cpu->GetInstructionSize() * 2;
-
- u32 result = lop ^ rop;
-
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(teq_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-TST_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- tst_inst* const inst_cream = (tst_inst*)inst_base->component;
-
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
-
- if (inst_cream->Rn == 15)
- lop += cpu->GetInstructionSize() * 2;
-
- u32 result = lop & rop;
-
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(tst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-UADD8_INST:
-UADD16_INST:
-UADDSUBX_INST:
-USUB8_INST:
-USUB16_INST:
-USUBADDX_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- s32 lo_result = 0;
- s32 hi_result = 0;
-
- // UADD16
- if (op2 == 0x00) {
- lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
-
- if (lo_result & 0xFFFF0000) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
-
- if (hi_result & 0xFFFF0000) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // UASX
- else if (op2 == 0x01) {
- lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
-
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
-
- if (hi_result >= 0x10000) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // USAX
- else if (op2 == 0x02) {
- lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
-
- if (lo_result >= 0x10000) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
-
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // USUB16
- else if (op2 == 0x03) {
- lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
-
- if ((lo_result & 0xFFFF0000) == 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
-
- if ((hi_result & 0xFFFF0000) == 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // UADD8
- else if (op2 == 0x04) {
- s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
-
- if (sum1 >= 0x100)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
-
- if (sum2 >= 0x100)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
-
- if (sum3 >= 0x100)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
-
- if (sum4 >= 0x100)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
-
- lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8);
- hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8);
- }
- // USUB8
- else if (op2 == 0x07) {
- s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
-
- if (diff1 >= 0)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
-
- if (diff2 >= 0)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
-
- if (diff3 >= 0)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
-
- if (diff4 >= 0)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
-
- lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8);
- hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8);
- }
-
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-UHADD8_INST:
-UHADD16_INST:
-UHADDSUBX_INST:
-UHSUBADDX_INST:
-UHSUB8_INST:
-UHSUB16_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u8 op2 = inst_cream->op2;
-
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- u32 lo_val = 0;
- u32 hi_val = 0;
-
- // UHADD16
- if (op2 == 0x00) {
- lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- }
- // UHASX
- else if (op2 == 0x01) {
- lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
- }
- // UHSAX
- else if (op2 == 0x02) {
- lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
- }
- // UHSUB16
- else if (op2 == 0x03) {
- lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- }
-
- lo_val >>= 1;
- hi_val >>= 1;
-
- RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
- } else if (op2 == 0x04 || op2 == 0x07) {
- u32 sum1;
- u32 sum2;
- u32 sum3;
- u32 sum4;
-
- // UHADD8
- if (op2 == 0x04) {
- sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
- }
- // UHSUB8
- else {
- sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
- }
-
- sum1 >>= 1;
- sum2 >>= 1;
- sum3 >>= 1;
- sum4 >>= 1;
-
- RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) |
- ((sum4 & 0xFF) << 24);
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-UMAAL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
- const u64 rm = RM;
- const u64 rn = RN;
- const u64 rd_lo = RDLO;
- const u64 rd_hi = RDHI;
- const u64 result = (rm * rn) + rd_lo + rd_hi;
-
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umaal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-UMLAL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- unsigned long long int add = ((unsigned long long)RDHI) << 32;
- add += RDLO;
- rst += add;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-UMULL_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-B_2_THUMB : {
- b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component;
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- INC_PC(sizeof(b_2_thumb));
- goto DISPATCH;
-}
-B_COND_THUMB : {
- b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component;
-
- if (CondPassed(cpu, inst_cream->cond))
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- else
- cpu->Reg[15] += 2;
-
- INC_PC(sizeof(b_cond_thumb));
- goto DISPATCH;
-}
-BL_1_THUMB : {
- bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
- cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bl_1_thumb));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-BL_2_THUMB : {
- bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component;
- int tmp = ((cpu->Reg[15] + 2) | 1);
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
- cpu->Reg[14] = tmp;
- INC_PC(sizeof(bl_2_thumb));
- goto DISPATCH;
-}
-BLX_1_THUMB : {
- // BLX 1 for armv5t and above
- u32 tmp = cpu->Reg[15];
- blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component;
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
- cpu->Reg[14] = ((tmp + 2) | 1);
- cpu->TFlag = 0;
- INC_PC(sizeof(blx_1_thumb));
- goto DISPATCH;
-}
-
-UQADD8_INST:
-UQADD16_INST:
-UQADDSUBX_INST:
-UQSUB8_INST:
-UQSUB16_INST:
-UQSUBADDX_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- u16 lo_val = 0;
- u16 hi_val = 0;
-
- // UQADD16
- if (op2 == 0x00) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- }
- // UQASX
- else if (op2 == 0x01) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
- }
- // UQSAX
- else if (op2 == 0x02) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
- }
- // UQSUB16
- else if (op2 == 0x03) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- }
- // UQADD8
- else if (op2 == 0x04) {
- lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
- }
- // UQSUB8
- else {
- lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
- }
-
- RD = ((lo_val & 0xFFFF) | hi_val << 16);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-USAD8_INST:
-USADA8_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 ra_idx = inst_cream->Ra;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
-
- const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
- const u8 diff2 =
- ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
- const u8 diff3 =
- ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
- const u8 diff4 =
- ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
-
- u32 finalDif = (diff1 + diff2 + diff3 + diff4);
-
- // Op is USADA8 if true.
- if (ra_idx != 15)
- finalDif += cpu->Reg[ra_idx];
-
- RD = finalDif;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-USAT_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
-
- u8 shift_type = inst_cream->shift_type;
- u8 shift_amount = inst_cream->imm5;
- u32 rn_val = RN;
-
- // 32-bit ASR is encoded as an amount of 0.
- if (shift_type == 1 && shift_amount == 0)
- shift_amount = 31;
-
- if (shift_type == 0)
- rn_val <<= shift_amount;
- else if (shift_type == 1)
- rn_val = ((s32)rn_val >> shift_amount);
-
- bool saturated = false;
- rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
-
- if (saturated)
- cpu->Cpsr |= (1 << 27);
-
- RD = rn_val;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-USAT16_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- const u8 saturate_to = inst_cream->sat_imm;
-
- bool sat1 = false;
- bool sat2 = false;
-
- RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
- ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
-
- if (sat1 || sat2)
- cpu->Cpsr |= (1 << 27);
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-UXTAB16_INST:
-UXTB16_INST : {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
-
- const u8 rn_idx = inst_cream->Rn;
- const u32 rm_val = RM;
- const u32 rotation = inst_cream->rotate * 8;
- const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
-
- // UXTB16, otherwise UXTAB16
- if (rn_idx == 15) {
- RD = rotated_rm & 0x00FF00FF;
- } else {
- const u32 rn_val = RN;
- const u8 lo_rotated = (rotated_rm & 0xFF);
- const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
- const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
- const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
-
- RD = ((hi_result << 16) | (lo_result & 0xFFFF));
- }
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-WFE_INST : {
- // Stubbed, as WFE is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM, "WFE executed.");
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-WFI_INST : {
- // Stubbed, as WFI is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM, "WFI executed.");
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-YIELD_INST : {
- // Stubbed, as YIELD is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM, "YIELD executed.");
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
-}
-
-#define VFP_INTERPRETER_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_INTERPRETER_IMPL
-
-END : {
- SAVE_NZCVT;
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
-}
-INIT_INST_LENGTH : {
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
-}
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h
deleted file mode 100644
index 7a46dcc94..000000000
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-struct ARMul_State;
-
-unsigned InterpreterMainLoop(ARMul_State* state);
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
deleted file mode 100644
index 8eb694fee..000000000
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (C)
-* 2011 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-
-#pragma once
-
-#include "core/arm/skyeye_common/armstate.h"
-
-/**
- * Checks if the PC is being read, and if so, word-aligns it.
- * Used with address calculations.
- *
- * @param cpu The ARM CPU state instance.
- * @param Rn The register being read.
- *
- * @return If the PC is being read, then the word-aligned PC value is returned.
- * If the PC is not being read, then the value stored in the register is returned.
- */
-inline u32 CHECK_READ_REG15_WA(const ARMul_State* cpu, int Rn) {
- return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
-}
-
-/**
- * Reads the PC. Used for data processing operations that use the PC.
- *
- * @param cpu The ARM CPU state instance.
- * @param Rn The register being read.
- *
- * @return If the PC is being read, then the incremented PC value is returned.
- * If the PC is not being read, then the values stored in the register is returned.
- */
-inline u32 CHECK_READ_REG15(const ARMul_State* cpu, int Rn) {
- return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn];
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
deleted file mode 100644
index 2a3dd0f53..000000000
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright 2012 Michael Kang, 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <cstddef>
-
-// We can provide simple Thumb simulation by decoding the Thumb instruction into its corresponding
-// ARM instruction, and using the existing ARM simulator.
-
-#include "core/arm/dyncom/arm_dyncom_thumb.h"
-#include "core/arm/skyeye_common/armsupp.h"
-
-// Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field,
-// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
-// allows easier simulation of the special dual BL instruction.
-
-ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
- ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED;
- u32 tinstr = GetThumbInstruction(instr, addr);
-
- *ainstr = 0xDEADC0DE; // Debugging to catch non updates
-
- switch ((tinstr & 0xF800) >> 11) {
- case 0: // LSL
- case 1: // LSR
- case 2: // ASR
- *ainstr = 0xE1B00000 // base opcode
- | ((tinstr & 0x1800) >> (11 - 5)) // shift type
- | ((tinstr & 0x07C0) << (7 - 6)) // imm5
- | ((tinstr & 0x0038) >> 3) // Rs
- | ((tinstr & 0x0007) << 12); // Rd
- break;
-
- case 3: // ADD/SUB
- {
- static const u32 subset[4] = {
- 0xE0900000, // ADDS Rd,Rs,Rn
- 0xE0500000, // SUBS Rd,Rs,Rn
- 0xE2900000, // ADDS Rd,Rs,#imm3
- 0xE2500000 // SUBS Rd,Rs,#imm3
- };
- // It is quicker indexing into a table, than performing switch or conditionals:
- *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode
- | ((tinstr & 0x01C0) >> 6) // Rn or imm3
- | ((tinstr & 0x0038) << (16 - 3)) // Rs
- | ((tinstr & 0x0007) << (12 - 0)); // Rd
- } break;
-
- case 4: // MOV
- case 5: // CMP
- case 6: // ADD
- case 7: // SUB
- {
- static const u32 subset[4] = {
- 0xE3B00000, // MOVS Rd,#imm8
- 0xE3500000, // CMP Rd,#imm8
- 0xE2900000, // ADDS Rd,Rd,#imm8
- 0xE2500000, // SUBS Rd,Rd,#imm8
- };
-
- *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode
- | ((tinstr & 0x00FF) >> 0) // imm8
- | ((tinstr & 0x0700) << (16 - 8)) // Rn
- | ((tinstr & 0x0700) << (12 - 8)); // Rd
- } break;
-
- case 8: // Arithmetic and high register transfers
-
- // TODO: Since the subsets for both Format 4 and Format 5 instructions are made up of
- // different ARM encodings, we could save the following conditional, and just have one
- // large subset
-
- if ((tinstr & (1 << 10)) == 0) {
- enum otype { t_norm, t_shift, t_neg, t_mul };
-
- static const struct {
- u32 opcode;
- otype type;
- } subset[16] = {
- {0xE0100000, t_norm}, // ANDS Rd,Rd,Rs
- {0xE0300000, t_norm}, // EORS Rd,Rd,Rs
- {0xE1B00010, t_shift}, // MOVS Rd,Rd,LSL Rs
- {0xE1B00030, t_shift}, // MOVS Rd,Rd,LSR Rs
- {0xE1B00050, t_shift}, // MOVS Rd,Rd,ASR Rs
- {0xE0B00000, t_norm}, // ADCS Rd,Rd,Rs
- {0xE0D00000, t_norm}, // SBCS Rd,Rd,Rs
- {0xE1B00070, t_shift}, // MOVS Rd,Rd,ROR Rs
- {0xE1100000, t_norm}, // TST Rd,Rs
- {0xE2700000, t_neg}, // RSBS Rd,Rs,#0
- {0xE1500000, t_norm}, // CMP Rd,Rs
- {0xE1700000, t_norm}, // CMN Rd,Rs
- {0xE1900000, t_norm}, // ORRS Rd,Rd,Rs
- {0xE0100090, t_mul}, // MULS Rd,Rd,Rs
- {0xE1D00000, t_norm}, // BICS Rd,Rd,Rs
- {0xE1F00000, t_norm} // MVNS Rd,Rs
- };
-
- *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base
-
- switch (subset[(tinstr & 0x03C0) >> 6].type) {
- case t_norm:
- *ainstr |= ((tinstr & 0x0007) << 16) // Rn
- | ((tinstr & 0x0007) << 12) // Rd
- | ((tinstr & 0x0038) >> 3); // Rs
- break;
- case t_shift:
- *ainstr |= ((tinstr & 0x0007) << 12) // Rd
- | ((tinstr & 0x0007) >> 0) // Rm
- | ((tinstr & 0x0038) << (8 - 3)); // Rs
- break;
- case t_neg:
- *ainstr |= ((tinstr & 0x0007) << 12) // Rd
- | ((tinstr & 0x0038) << (16 - 3)); // Rn
- break;
- case t_mul:
- *ainstr |= ((tinstr & 0x0007) << 16) // Rd
- | ((tinstr & 0x0007) << 8) // Rs
- | ((tinstr & 0x0038) >> 3); // Rm
- break;
- }
- } else {
- u32 Rd = ((tinstr & 0x0007) >> 0);
- u32 Rs = ((tinstr & 0x0078) >> 3);
-
- if (tinstr & (1 << 7))
- Rd += 8;
-
- switch ((tinstr & 0x03C0) >> 6) {
- case 0x0: // ADD Rd,Rd,Rs
- case 0x1: // ADD Rd,Rd,Hs
- case 0x2: // ADD Hd,Hd,Rs
- case 0x3: // ADD Hd,Hd,Hs
- *ainstr = 0xE0800000 // base
- | (Rd << 16) // Rn
- | (Rd << 12) // Rd
- | (Rs << 0); // Rm
- break;
- case 0x4: // CMP Rd,Rs
- case 0x5: // CMP Rd,Hs
- case 0x6: // CMP Hd,Rs
- case 0x7: // CMP Hd,Hs
- *ainstr = 0xE1500000 // base
- | (Rd << 16) // Rn
- | (Rs << 0); // Rm
- break;
- case 0x8: // MOV Rd,Rs
- case 0x9: // MOV Rd,Hs
- case 0xA: // MOV Hd,Rs
- case 0xB: // MOV Hd,Hs
- *ainstr = 0xE1A00000 // base
- | (Rd << 12) // Rd
- | (Rs << 0); // Rm
- break;
- case 0xC: // BX Rs
- case 0xD: // BX Hs
- *ainstr = 0xE12FFF10 // base
- | ((tinstr & 0x0078) >> 3); // Rd
- break;
- case 0xE: // BLX
- case 0xF: // BLX
- *ainstr = 0xE1200030 // base
- | (Rs << 0); // Rm
- break;
- }
- }
- break;
-
- case 9: // LDR Rd,[PC,#imm8]
- *ainstr = 0xE59F0000 // base
- | ((tinstr & 0x0700) << (12 - 8)) // Rd
- | ((tinstr & 0x00FF) << (2 - 0)); // off8
- break;
-
- case 10:
- case 11: {
- static const u32 subset[8] = {
- 0xE7800000, // STR Rd,[Rb,Ro]
- 0xE18000B0, // STRH Rd,[Rb,Ro]
- 0xE7C00000, // STRB Rd,[Rb,Ro]
- 0xE19000D0, // LDRSB Rd,[Rb,Ro]
- 0xE7900000, // LDR Rd,[Rb,Ro]
- 0xE19000B0, // LDRH Rd,[Rb,Ro]
- 0xE7D00000, // LDRB Rd,[Rb,Ro]
- 0xE19000F0 // LDRSH Rd,[Rb,Ro]
- };
-
- *ainstr = subset[(tinstr & 0xE00) >> 9] // base
- | ((tinstr & 0x0007) << (12 - 0)) // Rd
- | ((tinstr & 0x0038) << (16 - 3)) // Rb
- | ((tinstr & 0x01C0) >> 6); // Ro
- } break;
-
- case 12: // STR Rd,[Rb,#imm5]
- case 13: // LDR Rd,[Rb,#imm5]
- case 14: // STRB Rd,[Rb,#imm5]
- case 15: // LDRB Rd,[Rb,#imm5]
- {
- static const u32 subset[4] = {
- 0xE5800000, // STR Rd,[Rb,#imm5]
- 0xE5900000, // LDR Rd,[Rb,#imm5]
- 0xE5C00000, // STRB Rd,[Rb,#imm5]
- 0xE5D00000 // LDRB Rd,[Rb,#imm5]
- };
- // The offset range defends on whether we are transferring a byte or word value:
- *ainstr = subset[(tinstr & 0x1800) >> 11] // base
- | ((tinstr & 0x0007) << (12 - 0)) // Rd
- | ((tinstr & 0x0038) << (16 - 3)) // Rb
- | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5
- } break;
-
- case 16: // STRH Rd,[Rb,#imm5]
- case 17: // LDRH Rd,[Rb,#imm5]
- *ainstr = ((tinstr & (1 << 11)) // base
- ? 0xE1D000B0 // LDRH
- : 0xE1C000B0) // STRH
- | ((tinstr & 0x0007) << (12 - 0)) // Rd
- | ((tinstr & 0x0038) << (16 - 3)) // Rb
- | ((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble
- | ((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble
- break;
-
- case 18: // STR Rd,[SP,#imm8]
- case 19: // LDR Rd,[SP,#imm8]
- *ainstr = ((tinstr & (1 << 11)) // base
- ? 0xE59D0000 // LDR
- : 0xE58D0000) // STR
- | ((tinstr & 0x0700) << (12 - 8)) // Rd
- | ((tinstr & 0x00FF) << 2); // off8
- break;
-
- case 20: // ADD Rd,PC,#imm8
- case 21: // ADD Rd,SP,#imm8
-
- if ((tinstr & (1 << 11)) == 0) {
-
- // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the
- // rotate immediate field, so no shift of off8 is needed.
-
- *ainstr = 0xE28F0F00 // base
- | ((tinstr & 0x0700) << (12 - 8)) // Rd
- | (tinstr & 0x00FF); // off8
- } else {
- // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is
- // needed.
- *ainstr = 0xE28D0F00 // base
- | ((tinstr & 0x0700) << (12 - 8)) // Rd
- | (tinstr & 0x00FF); // off8
- }
- break;
-
- case 22:
- case 23:
- if ((tinstr & 0x0F00) == 0x0000) {
- // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30):
- *ainstr = ((tinstr & (1 << 7)) // base
- ? 0xE24DDF00 // SUB
- : 0xE28DDF00) // ADD
- | (tinstr & 0x007F); // off7
- } else if ((tinstr & 0x0F00) == 0x0e00) {
- // BKPT
- *ainstr = 0xEF000000 // base
- | BITS(tinstr, 0, 3) // imm4 field;
- | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12
- } else if ((tinstr & 0x0F00) == 0x0200) {
- static const u32 subset[4] = {
- 0xE6BF0070, // SXTH
- 0xE6AF0070, // SXTB
- 0xE6FF0070, // UXTH
- 0xE6EF0070, // UXTB
- };
-
- *ainstr = subset[BITS(tinstr, 6, 7)] // base
- | (BITS(tinstr, 0, 2) << 12) // Rd
- | BITS(tinstr, 3, 5); // Rm
- } else if ((tinstr & 0x0F00) == 0x600) {
- if (BIT(tinstr, 5) == 0) {
- // SETEND
- *ainstr = 0xF1010000 // base
- | (BIT(tinstr, 3) << 9); // endian specifier
- } else {
- // CPS
- *ainstr = 0xF1080000 // base
- | (BIT(tinstr, 0) << 6) // fiq bit
- | (BIT(tinstr, 1) << 7) // irq bit
- | (BIT(tinstr, 2) << 8) // abort bit
- | (BIT(tinstr, 4) << 18); // enable bit
- }
- } else if ((tinstr & 0x0F00) == 0x0a00) {
- static const u32 subset[4] = {
- 0xE6BF0F30, // REV
- 0xE6BF0FB0, // REV16
- 0, // undefined
- 0xE6FF0FB0, // REVSH
- };
-
- size_t subset_index = BITS(tinstr, 6, 7);
-
- if (subset_index == 2) {
- valid = ThumbDecodeStatus::UNDEFINED;
- } else {
- *ainstr = subset[subset_index] // base
- | (BITS(tinstr, 0, 2) << 12) // Rd
- | BITS(tinstr, 3, 5); // Rm
- }
- } else {
- static const u32 subset[4] = {
- 0xE92D0000, // STMDB sp!,{rlist}
- 0xE92D4000, // STMDB sp!,{rlist,lr}
- 0xE8BD0000, // LDMIA sp!,{rlist}
- 0xE8BD8000 // LDMIA sp!,{rlist,pc}
- };
- *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base
- | (tinstr & 0x00FF); // mask8
- }
- break;
-
- case 24: // STMIA
- case 25: // LDMIA
- if (tinstr & (1 << 11)) {
- unsigned int base = 0xE8900000;
- unsigned int rn = BITS(tinstr, 8, 10);
-
- // Writeback
- if ((tinstr & (1 << rn)) == 0)
- base |= (1 << 21);
-
- *ainstr = base // base (LDMIA)
- | (rn << 16) // Rn
- | (tinstr & 0x00FF); // Register list
- } else {
- *ainstr = 0xE8A00000 // base (STMIA)
- | (BITS(tinstr, 8, 10) << 16) // Rn
- | (tinstr & 0x00FF); // Register list
- }
- break;
-
- case 26: // Bcc
- case 27: // Bcc/SWI
- if ((tinstr & 0x0F00) == 0x0F00) {
- // Format 17 : SWI
- *ainstr = 0xEF000000;
- // Breakpoint must be handled specially.
- if ((tinstr & 0x00FF) == 0x18)
- *ainstr |= ((tinstr & 0x00FF) << 16);
- // New breakpoint value. See gdb/arm-tdep.c
- else if ((tinstr & 0x00FF) == 0xFE)
- *ainstr |= 0x180000; // base |= BKPT mask
- else
- *ainstr |= (tinstr & 0x00FF);
- } else if ((tinstr & 0x0F00) != 0x0E00)
- valid = ThumbDecodeStatus::BRANCH;
- else // UNDEFINED : cc=1110(AL) uses different format
- valid = ThumbDecodeStatus::UNDEFINED;
-
- break;
-
- case 28: // B
- valid = ThumbDecodeStatus::BRANCH;
- break;
-
- case 29:
- if (tinstr & 0x1)
- valid = ThumbDecodeStatus::UNDEFINED;
- else
- valid = ThumbDecodeStatus::BRANCH;
- break;
-
- case 30: // BL instruction 1
-
- // There is no single ARM instruction equivalent for this Thumb instruction. To keep the
- // simulation simple (from the user perspective) we check if the following instruction is
- // the second half of this BL, and if it is we simulate it immediately
-
- valid = ThumbDecodeStatus::BRANCH;
- break;
-
- case 31: // BL instruction 2
-
- // There is no single ARM instruction equivalent for this instruction. Also, it should only
- // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
- // simulation of it on its own, with undefined results if r14 is not suitably initialised.
-
- valid = ThumbDecodeStatus::BRANCH;
- break;
- }
-
- *inst_size = 2;
-
- return valid;
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
deleted file mode 100644
index 231e48aa4..000000000
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C)
-* 2011 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-
-/**
-* @file arm_dyncom_thumb.h
-* @brief The thumb dyncom
-* @author Michael.Kang blackfin.kang@gmail.com
-* @version 78.77
-* @date 2011-11-07
-*/
-
-#pragma once
-
-#include "common/common_types.h"
-
-enum class ThumbDecodeStatus {
- UNDEFINED, // Undefined Thumb instruction
- DECODED, // Instruction decoded to ARM equivalent
- BRANCH, // Thumb branch (already processed)
- UNINITIALIZED,
-};
-
-// Translates a Thumb mode instruction into its ARM equivalent.
-ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
-
-inline u32 GetThumbInstruction(u32 instr, u32 address) {
- // Normally you would need to handle instruction endianness,
- // however, it is fixed to little-endian on the MPCore, so
- // there's no need to check for this beforehand.
- if ((address & 0x3) != 0)
- return instr >> 16;
-
- return instr & 0xFFFF;
-}
diff --git a/src/core/arm/dyncom/arm_dyncom_trans.cpp b/src/core/arm/dyncom/arm_dyncom_trans.cpp
deleted file mode 100644
index 9cd6c0dea..000000000
--- a/src/core/arm/dyncom/arm_dyncom_trans.cpp
+++ /dev/null
@@ -1,1887 +0,0 @@
-#include <cstdlib>
-#include "common/assert.h"
-#include "common/common_types.h"
-#include "core/arm/dyncom/arm_dyncom_interpreter.h"
-#include "core/arm/dyncom/arm_dyncom_trans.h"
-#include "core/arm/skyeye_common/armstate.h"
-#include "core/arm/skyeye_common/armsupp.h"
-#include "core/arm/skyeye_common/vfp/vfp.h"
-
-char trans_cache_buf[TRANS_CACHE_SIZE];
-size_t trans_cache_buf_top = 0;
-
-static void* AllocBuffer(size_t size) {
- size_t start = trans_cache_buf_top;
- trans_cache_buf_top += size;
- ASSERT_MSG(trans_cache_buf_top <= TRANS_CACHE_SIZE, "Translation cache is full!");
- return static_cast<void*>(&trans_cache_buf[start]);
-}
-
-#define glue(x, y) x##y
-#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
-
-shtop_fp_t GetShifterOp(unsigned int inst);
-get_addr_fp_t GetAddressingOp(unsigned int inst);
-get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst);
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
- adc_inst* inst_cream = (adc_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
- add_inst* inst_cream = (add_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
- and_inst* inst_cream = (and_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) {
-#define POSBRANCH ((inst & 0x7fffff) << 2)
-#define NEGBRANCH ((0xff000000 | (inst & 0xffffff)) << 2)
-
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
- bbl_inst* inst_cream = (bbl_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::DIRECT_BRANCH;
-
- if (BIT(inst, 24))
- inst_base->br = TransExtData::CALL;
-
- inst_cream->L = BIT(inst, 24);
- inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
- bic_inst* inst_cream = (bic_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bkpt_inst));
- bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->imm = (BITS(inst, 8, 19) << 4) | BITS(inst, 0, 3);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
- blx_inst* inst_cream = (blx_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- inst_cream->inst = inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- inst_cream->val.Rm = BITS(inst, 0, 3);
- } else {
- inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
- }
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
- bx_inst* inst_cream = (bx_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(bx)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
- cdp_inst* inst_cream = (cdp_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->CRm = BITS(inst, 0, 3);
- inst_cream->CRd = BITS(inst, 12, 15);
- inst_cream->CRn = BITS(inst, 16, 19);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->opcode_1 = BITS(inst, 20, 23);
- inst_cream->inst = inst;
-
- LOG_TRACE(Core_ARM, "inst %x index %x", inst, index);
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
- clz_inst* inst_cream = (clz_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
- cmn_inst* inst_cream = (cmn_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
- cmp_inst* inst_cream = (cmp_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
- cps_inst* inst_cream = (cps_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->imod0 = BIT(inst, 18);
- inst_cream->imod1 = BIT(inst, 19);
- inst_cream->mmod = BIT(inst, 17);
- inst_cream->A = BIT(inst, 8);
- inst_cream->I = BIT(inst, 7);
- inst_cream->F = BIT(inst, 6);
- inst_cream->mode = BITS(inst, 0, 4);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15) {
- inst_base->br = TransExtData::INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
- eor_inst* inst_cream = (eor_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- if (BIT(inst, 15)) {
- inst_base->br = TransExtData::INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- if (BITS(inst, 12, 15) == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- if (BITS(inst, 12, 15) == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
- uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = (BITS(inst, 12, 15) == 15) ? TransExtData::INDIRECT_BRANCH
- : TransExtData::NON_BRANCH; // Branch if dest is R15
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
-
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = TransExtData::INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
- mcr_inst* inst_cream = (mcr_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcrr_inst));
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 4, 7);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->rt = BITS(inst, 12, 15);
- inst_cream->rt2 = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
- mla_inst* inst_cream = (mla_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 12, 15);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15) {
- inst_base->br = TransExtData::INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
- mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(mcrr)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
- mrs_inst* inst_cream = (mrs_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->R = BIT(inst, 22);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
- msr_inst* inst_cream = (msr_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->field_mask = BITS(inst, 16, 19);
- inst_cream->R = BIT(inst, 22);
- inst_cream->inst = inst;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
- mul_inst* inst_cream = (mul_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
- mvn_inst* inst_cream = (mvn_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15) {
- inst_base->br = TransExtData::INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
- orr_inst* inst_cream = (orr_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-
-// NOP introduced in ARMv6K.
-static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
- pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->imm = BITS(inst, 7, 11);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 21, 22);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst* const inst_cream = (rev_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(rev)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(rev)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
- rsb_inst* inst_cream = (rsb_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
- rsc_inst* inst_cream = (rsc_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
- sbc_inst* inst_cream = (sbc_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(setend_inst));
- setend_inst* const inst_cream = (setend_inst*)inst_base->component;
-
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->set_bigend = BIT(inst, 9);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
- smla_inst* inst_cream = (smla_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->m = BIT(inst, 5);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlalxy_inst));
- smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 0, 4);
- inst_cream->Rm = BITS(inst, 8, 11);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->m = BIT(inst, 6);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst));
- smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->swap = BIT(inst, 5);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(smlald)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->m = BIT(inst, 5);
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(smmla)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(smmla)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
- smul_inst* inst_cream = (smul_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->m = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->imm5 = BITS(inst, 7, 11);
- inst_cream->sat_imm = BITS(inst, 16, 20);
- inst_cream->shift_type = BIT(inst, 6);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->sat_imm = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(strex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(strex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(strex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
- sub_inst* inst_cream = (sub_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = TransExtData::INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
- swi_inst* inst_cream = (swi_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->num = BITS(inst, 0, 23);
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(sxtab16)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
- sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
- teq_inst* inst_cream = (teq_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
- tst_inst* inst_cream = (tst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = GetShifterOp(inst);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
- b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component;
-
- inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
-
- inst_base->idx = index;
- inst_base->br = TransExtData::DIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
- b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component;
-
- inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
- inst_cream->cond = ((tinst >> 8) & 0xf);
- inst_base->idx = index;
- inst_base->br = TransExtData::DIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
- bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
-
- inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
-
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
- bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component;
-
- inst_cream->imm = (tinst & 0x07FF) << 1;
-
- inst_base->idx = index;
- inst_base->br = TransExtData::DIRECT_BRANCH;
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) {
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
- blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component;
-
- inst_cream->imm = (tinst & 0x07FF) << 1;
- inst_cream->instr = tinst;
-
- inst_base->idx = index;
- inst_base->br = TransExtData::DIRECT_BRANCH;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 24);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Ra = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(usada8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(ssat)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(ssat16)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) {
- return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index) {
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = TransExtData::NON_BRANCH;
-
- return inst_base;
-}
-
-// Floating point VFPv3 instructions
-#define VFP_INTERPRETER_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_INTERPRETER_TRANS
-
-const transop_fp_t arm_instruction_trans[] = {
- INTERPRETER_TRANSLATE(vmla), INTERPRETER_TRANSLATE(vmls), INTERPRETER_TRANSLATE(vnmla),
- INTERPRETER_TRANSLATE(vnmls), INTERPRETER_TRANSLATE(vnmul), INTERPRETER_TRANSLATE(vmul),
- INTERPRETER_TRANSLATE(vadd), INTERPRETER_TRANSLATE(vsub), INTERPRETER_TRANSLATE(vdiv),
- INTERPRETER_TRANSLATE(vmovi), INTERPRETER_TRANSLATE(vmovr), INTERPRETER_TRANSLATE(vabs),
- INTERPRETER_TRANSLATE(vneg), INTERPRETER_TRANSLATE(vsqrt), INTERPRETER_TRANSLATE(vcmp),
- INTERPRETER_TRANSLATE(vcmp2), INTERPRETER_TRANSLATE(vcvtbds), INTERPRETER_TRANSLATE(vcvtbff),
- INTERPRETER_TRANSLATE(vcvtbfi), INTERPRETER_TRANSLATE(vmovbrs), INTERPRETER_TRANSLATE(vmsr),
- INTERPRETER_TRANSLATE(vmovbrc), INTERPRETER_TRANSLATE(vmrs), INTERPRETER_TRANSLATE(vmovbcr),
- INTERPRETER_TRANSLATE(vmovbrrss), INTERPRETER_TRANSLATE(vmovbrrd), INTERPRETER_TRANSLATE(vstr),
- INTERPRETER_TRANSLATE(vpush), INTERPRETER_TRANSLATE(vstm), INTERPRETER_TRANSLATE(vpop),
- INTERPRETER_TRANSLATE(vldr), INTERPRETER_TRANSLATE(vldm),
-
- INTERPRETER_TRANSLATE(srs), INTERPRETER_TRANSLATE(rfe), INTERPRETER_TRANSLATE(bkpt),
- INTERPRETER_TRANSLATE(blx), INTERPRETER_TRANSLATE(cps), INTERPRETER_TRANSLATE(pld),
- INTERPRETER_TRANSLATE(setend), INTERPRETER_TRANSLATE(clrex), INTERPRETER_TRANSLATE(rev16),
- INTERPRETER_TRANSLATE(usad8), INTERPRETER_TRANSLATE(sxtb), INTERPRETER_TRANSLATE(uxtb),
- INTERPRETER_TRANSLATE(sxth), INTERPRETER_TRANSLATE(sxtb16), INTERPRETER_TRANSLATE(uxth),
- INTERPRETER_TRANSLATE(uxtb16), INTERPRETER_TRANSLATE(cpy), INTERPRETER_TRANSLATE(uxtab),
- INTERPRETER_TRANSLATE(ssub8), INTERPRETER_TRANSLATE(shsub8), INTERPRETER_TRANSLATE(ssubaddx),
- INTERPRETER_TRANSLATE(strex), INTERPRETER_TRANSLATE(strexb), INTERPRETER_TRANSLATE(swp),
- INTERPRETER_TRANSLATE(swpb), INTERPRETER_TRANSLATE(ssub16), INTERPRETER_TRANSLATE(ssat16),
- INTERPRETER_TRANSLATE(shsubaddx), INTERPRETER_TRANSLATE(qsubaddx),
- INTERPRETER_TRANSLATE(shaddsubx), INTERPRETER_TRANSLATE(shadd8), INTERPRETER_TRANSLATE(shadd16),
- INTERPRETER_TRANSLATE(sel), INTERPRETER_TRANSLATE(saddsubx), INTERPRETER_TRANSLATE(sadd8),
- INTERPRETER_TRANSLATE(sadd16), INTERPRETER_TRANSLATE(shsub16), INTERPRETER_TRANSLATE(umaal),
- INTERPRETER_TRANSLATE(uxtab16), INTERPRETER_TRANSLATE(usubaddx), INTERPRETER_TRANSLATE(usub8),
- INTERPRETER_TRANSLATE(usub16), INTERPRETER_TRANSLATE(usat16), INTERPRETER_TRANSLATE(usada8),
- INTERPRETER_TRANSLATE(uqsubaddx), INTERPRETER_TRANSLATE(uqsub8), INTERPRETER_TRANSLATE(uqsub16),
- INTERPRETER_TRANSLATE(uqaddsubx), INTERPRETER_TRANSLATE(uqadd8), INTERPRETER_TRANSLATE(uqadd16),
- INTERPRETER_TRANSLATE(sxtab), INTERPRETER_TRANSLATE(uhsubaddx), INTERPRETER_TRANSLATE(uhsub8),
- INTERPRETER_TRANSLATE(uhsub16), INTERPRETER_TRANSLATE(uhaddsubx), INTERPRETER_TRANSLATE(uhadd8),
- INTERPRETER_TRANSLATE(uhadd16), INTERPRETER_TRANSLATE(uaddsubx), INTERPRETER_TRANSLATE(uadd8),
- INTERPRETER_TRANSLATE(uadd16), INTERPRETER_TRANSLATE(sxtah), INTERPRETER_TRANSLATE(sxtab16),
- INTERPRETER_TRANSLATE(qadd8), INTERPRETER_TRANSLATE(bxj), INTERPRETER_TRANSLATE(clz),
- INTERPRETER_TRANSLATE(uxtah), INTERPRETER_TRANSLATE(bx), INTERPRETER_TRANSLATE(rev),
- INTERPRETER_TRANSLATE(blx), INTERPRETER_TRANSLATE(revsh), INTERPRETER_TRANSLATE(qadd),
- INTERPRETER_TRANSLATE(qadd16), INTERPRETER_TRANSLATE(qaddsubx), INTERPRETER_TRANSLATE(ldrex),
- INTERPRETER_TRANSLATE(qdadd), INTERPRETER_TRANSLATE(qdsub), INTERPRETER_TRANSLATE(qsub),
- INTERPRETER_TRANSLATE(ldrexb), INTERPRETER_TRANSLATE(qsub8), INTERPRETER_TRANSLATE(qsub16),
- INTERPRETER_TRANSLATE(smuad), INTERPRETER_TRANSLATE(smmul), INTERPRETER_TRANSLATE(smusd),
- INTERPRETER_TRANSLATE(smlsd), INTERPRETER_TRANSLATE(smlsld), INTERPRETER_TRANSLATE(smmla),
- INTERPRETER_TRANSLATE(smmls), INTERPRETER_TRANSLATE(smlald), INTERPRETER_TRANSLATE(smlad),
- INTERPRETER_TRANSLATE(smlaw), INTERPRETER_TRANSLATE(smulw), INTERPRETER_TRANSLATE(pkhtb),
- INTERPRETER_TRANSLATE(pkhbt), INTERPRETER_TRANSLATE(smul), INTERPRETER_TRANSLATE(smlalxy),
- INTERPRETER_TRANSLATE(smla), INTERPRETER_TRANSLATE(mcrr), INTERPRETER_TRANSLATE(mrrc),
- INTERPRETER_TRANSLATE(cmp), INTERPRETER_TRANSLATE(tst), INTERPRETER_TRANSLATE(teq),
- INTERPRETER_TRANSLATE(cmn), INTERPRETER_TRANSLATE(smull), INTERPRETER_TRANSLATE(umull),
- INTERPRETER_TRANSLATE(umlal), INTERPRETER_TRANSLATE(smlal), INTERPRETER_TRANSLATE(mul),
- INTERPRETER_TRANSLATE(mla), INTERPRETER_TRANSLATE(ssat), INTERPRETER_TRANSLATE(usat),
- INTERPRETER_TRANSLATE(mrs), INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(and),
- INTERPRETER_TRANSLATE(bic), INTERPRETER_TRANSLATE(ldm), INTERPRETER_TRANSLATE(eor),
- INTERPRETER_TRANSLATE(add), INTERPRETER_TRANSLATE(rsb), INTERPRETER_TRANSLATE(rsc),
- INTERPRETER_TRANSLATE(sbc), INTERPRETER_TRANSLATE(adc), INTERPRETER_TRANSLATE(sub),
- INTERPRETER_TRANSLATE(orr), INTERPRETER_TRANSLATE(mvn), INTERPRETER_TRANSLATE(mov),
- INTERPRETER_TRANSLATE(stm), INTERPRETER_TRANSLATE(ldm), INTERPRETER_TRANSLATE(ldrsh),
- INTERPRETER_TRANSLATE(stm), INTERPRETER_TRANSLATE(ldm), INTERPRETER_TRANSLATE(ldrsb),
- INTERPRETER_TRANSLATE(strd), INTERPRETER_TRANSLATE(ldrh), INTERPRETER_TRANSLATE(strh),
- INTERPRETER_TRANSLATE(ldrd), INTERPRETER_TRANSLATE(strt), INTERPRETER_TRANSLATE(strbt),
- INTERPRETER_TRANSLATE(ldrbt), INTERPRETER_TRANSLATE(ldrt), INTERPRETER_TRANSLATE(mrc),
- INTERPRETER_TRANSLATE(mcr), INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(ldrb), INTERPRETER_TRANSLATE(strb), INTERPRETER_TRANSLATE(ldr),
- INTERPRETER_TRANSLATE(ldrcond), INTERPRETER_TRANSLATE(str), INTERPRETER_TRANSLATE(cdp),
- INTERPRETER_TRANSLATE(stc), INTERPRETER_TRANSLATE(ldc), INTERPRETER_TRANSLATE(ldrexd),
- INTERPRETER_TRANSLATE(strexd), INTERPRETER_TRANSLATE(ldrexh), INTERPRETER_TRANSLATE(strexh),
- INTERPRETER_TRANSLATE(nop), INTERPRETER_TRANSLATE(yield), INTERPRETER_TRANSLATE(wfe),
- INTERPRETER_TRANSLATE(wfi), INTERPRETER_TRANSLATE(sev), INTERPRETER_TRANSLATE(swi),
- INTERPRETER_TRANSLATE(bbl),
-
- // All the thumb instructions should be placed the end of table
- INTERPRETER_TRANSLATE(b_2_thumb), INTERPRETER_TRANSLATE(b_cond_thumb),
- INTERPRETER_TRANSLATE(bl_1_thumb), INTERPRETER_TRANSLATE(bl_2_thumb),
- INTERPRETER_TRANSLATE(blx_1_thumb),
-};
-
-const size_t arm_instruction_trans_len = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
diff --git a/src/core/arm/dyncom/arm_dyncom_trans.h b/src/core/arm/dyncom/arm_dyncom_trans.h
deleted file mode 100644
index 632ff2cd6..000000000
--- a/src/core/arm/dyncom/arm_dyncom_trans.h
+++ /dev/null
@@ -1,494 +0,0 @@
-#pragma once
-
-#include <cstddef>
-#include "common/common_types.h"
-
-struct ARMul_State;
-typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
-
-enum class TransExtData {
- COND = (1 << 0),
- NON_BRANCH = (1 << 1),
- DIRECT_BRANCH = (1 << 2),
- INDIRECT_BRANCH = (1 << 3),
- CALL = (1 << 4),
- RET = (1 << 5),
- END_OF_PAGE = (1 << 6),
- THUMB = (1 << 7),
- SINGLE_STEP = (1 << 8)
-};
-
-struct arm_inst {
- unsigned int idx;
- unsigned int cond;
- TransExtData br;
- char component[0];
-};
-
-struct generic_arm_inst {
- u32 Ra;
- u32 Rm;
- u32 Rn;
- u32 Rd;
- u8 op1;
- u8 op2;
-};
-
-struct adc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct add_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct orr_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct and_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct eor_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct bbl_inst {
- unsigned int L;
- int signed_immed_24;
- unsigned int next_addr;
- unsigned int jmp_addr;
-};
-
-struct bx_inst {
- unsigned int Rm;
-};
-
-struct blx_inst {
- union {
- s32 signed_immed_24;
- u32 Rm;
- } val;
- unsigned int inst;
-};
-
-struct clz_inst {
- unsigned int Rm;
- unsigned int Rd;
-};
-
-struct cps_inst {
- unsigned int imod0;
- unsigned int imod1;
- unsigned int mmod;
- unsigned int A, I, F;
- unsigned int mode;
-};
-
-struct clrex_inst {};
-
-struct cpy_inst {
- unsigned int Rm;
- unsigned int Rd;
-};
-
-struct bic_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct sub_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct tst_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct cmn_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct teq_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct stm_inst {
- unsigned int inst;
-};
-
-struct bkpt_inst {
- u32 imm;
-};
-
-struct stc_inst {};
-
-struct ldc_inst {};
-
-struct swi_inst {
- unsigned int num;
-};
-
-struct cmp_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct mov_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct mvn_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct rev_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int op1;
- unsigned int op2;
-};
-
-struct rsb_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct rsc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct sbc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct mul_inst {
- unsigned int S;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
-};
-
-struct smul_inst {
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
- unsigned int x;
- unsigned int y;
-};
-
-struct umull_inst {
- unsigned int S;
- unsigned int RdHi;
- unsigned int RdLo;
- unsigned int Rs;
- unsigned int Rm;
-};
-
-struct smlad_inst {
- unsigned int m;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Ra;
- unsigned int Rn;
- unsigned int op1;
- unsigned int op2;
-};
-
-struct smla_inst {
- unsigned int x;
- unsigned int y;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rn;
-};
-
-struct smlalxy_inst {
- unsigned int x;
- unsigned int y;
- unsigned int RdLo;
- unsigned int RdHi;
- unsigned int Rm;
- unsigned int Rn;
-};
-
-struct ssat_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int imm5;
- unsigned int sat_imm;
- unsigned int shift_type;
-};
-
-struct umaal_inst {
- unsigned int Rn;
- unsigned int Rm;
- unsigned int RdHi;
- unsigned int RdLo;
-};
-
-struct umlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
-};
-
-struct smlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
-};
-
-struct smlald_inst {
- unsigned int RdLo;
- unsigned int RdHi;
- unsigned int Rm;
- unsigned int Rn;
- unsigned int swap;
- unsigned int op1;
- unsigned int op2;
-};
-
-struct mla_inst {
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
-};
-
-struct mrc_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
-};
-
-struct mcr_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
-};
-
-struct mcrr_inst {
- unsigned int opcode_1;
- unsigned int cp_num;
- unsigned int crm;
- unsigned int rt;
- unsigned int rt2;
-};
-
-struct mrs_inst {
- unsigned int R;
- unsigned int Rd;
-};
-
-struct msr_inst {
- unsigned int field_mask;
- unsigned int R;
- unsigned int inst;
-};
-
-struct pld_inst {};
-
-struct sxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct sxtab_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned rotate;
-};
-
-struct sxtah_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct sxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct uxtab_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
-};
-
-struct uxtah_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
-};
-
-struct uxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct cdp_inst {
- unsigned int opcode_1;
- unsigned int CRn;
- unsigned int CRd;
- unsigned int cp_num;
- unsigned int opcode_2;
- unsigned int CRm;
- unsigned int inst;
-};
-
-struct uxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct swp_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rm;
-};
-
-struct setend_inst {
- unsigned int set_bigend;
-};
-
-struct b_2_thumb {
- unsigned int imm;
-};
-struct b_cond_thumb {
- unsigned int imm;
- unsigned int cond;
-};
-
-struct bl_1_thumb {
- unsigned int imm;
-};
-struct bl_2_thumb {
- unsigned int imm;
-};
-struct blx_1_thumb {
- unsigned int imm;
- unsigned int instr;
-};
-
-struct pkh_inst {
- unsigned int Rm;
- unsigned int Rn;
- unsigned int Rd;
- unsigned char imm;
-};
-
-// Floating point VFPv3 structures
-#define VFP_INTERPRETER_STRUCT
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_INTERPRETER_STRUCT
-
-typedef void (*get_addr_fp_t)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr);
-
-struct ldst_inst {
- unsigned int inst;
- get_addr_fp_t get_addr;
-};
-
-typedef arm_inst* ARM_INST_PTR;
-typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
-
-extern const transop_fp_t arm_instruction_trans[];
-extern const size_t arm_instruction_trans_len;
-
-#define TRANS_CACHE_SIZE (64 * 1024 * 2000)
-extern char trans_cache_buf[TRANS_CACHE_SIZE];
-extern size_t trans_cache_buf_top;