From b172f0d770486d4367fbea22906a5e908ef621e8 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 2 Jan 2018 22:24:12 -0500 Subject: arm: Remove SkyEye/Dyncom code that is ARMv6-only. --- src/core/arm/dyncom/arm_dyncom.cpp | 132 - src/core/arm/dyncom/arm_dyncom.h | 46 - src/core/arm/dyncom/arm_dyncom_dec.cpp | 478 --- src/core/arm/dyncom/arm_dyncom_dec.h | 36 - src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 4578 ------------------------ src/core/arm/dyncom/arm_dyncom_interpreter.h | 9 - src/core/arm/dyncom/arm_dyncom_run.h | 48 - src/core/arm/dyncom/arm_dyncom_thumb.cpp | 390 -- src/core/arm/dyncom/arm_dyncom_thumb.h | 49 - src/core/arm/dyncom/arm_dyncom_trans.cpp | 1887 ---------- src/core/arm/dyncom/arm_dyncom_trans.h | 494 --- 11 files changed, 8147 deletions(-) delete mode 100644 src/core/arm/dyncom/arm_dyncom.cpp delete mode 100644 src/core/arm/dyncom/arm_dyncom.h delete mode 100644 src/core/arm/dyncom/arm_dyncom_dec.cpp delete mode 100644 src/core/arm/dyncom/arm_dyncom_dec.h delete mode 100644 src/core/arm/dyncom/arm_dyncom_interpreter.cpp delete mode 100644 src/core/arm/dyncom/arm_dyncom_interpreter.h delete mode 100644 src/core/arm/dyncom/arm_dyncom_run.h delete mode 100644 src/core/arm/dyncom/arm_dyncom_thumb.cpp delete mode 100644 src/core/arm/dyncom/arm_dyncom_thumb.h delete mode 100644 src/core/arm/dyncom/arm_dyncom_trans.cpp delete mode 100644 src/core/arm/dyncom/arm_dyncom_trans.h (limited to 'src/core/arm/dyncom') 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 -#include -#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(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 -#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 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 -#include -#include -#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(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(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(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(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(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(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((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((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(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 - -// 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 -#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(&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 -#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; -- cgit v1.2.3