A32: Merge ArmTranslateVistor and ThumbTranslateVisitor

This commit is contained in:
MerryMage 2021-05-03 22:20:05 +01:00
parent 6d292e3eac
commit cd837c5b37
51 changed files with 1635 additions and 1729 deletions

View file

@ -171,8 +171,8 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
frontend/A32/translate/impl/thumb32_multiply.cpp frontend/A32/translate/impl/thumb32_multiply.cpp
frontend/A32/translate/impl/thumb32_parallel.cpp frontend/A32/translate/impl/thumb32_parallel.cpp
frontend/A32/translate/impl/thumb32_store_single_data_item.cpp frontend/A32/translate/impl/thumb32_store_single_data_item.cpp
frontend/A32/translate/impl/translate_arm.h frontend/A32/translate/impl/translate.cpp
frontend/A32/translate/impl/translate_thumb.h frontend/A32/translate/impl/translate.h
frontend/A32/translate/impl/vfp.cpp frontend/A32/translate/impl/vfp.cpp
frontend/A32/translate/translate.cpp frontend/A32/translate/translate.cpp
frontend/A32/translate/translate.h frontend/A32/translate/translate.h

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
#include <optional> #include <optional>
#include <tuple> #include <tuple>
@ -72,7 +72,7 @@ std::optional<std::tuple<size_t, size_t, size_t>> DecodeType(Imm<4> type, size_t
} }
} // anoynmous namespace } // anoynmous namespace
bool ArmTranslatorVisitor::v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t size, size_t align, Reg m) { bool TranslatorVisitor::v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t size, size_t align, Reg m) {
if (type == 0b1011 || type.Bits<2, 3>() == 0b11) { if (type == 0b1011 || type.Bits<2, 3>() == 0b11) {
return DecodeError(); return DecodeError();
} }
@ -121,7 +121,7 @@ bool ArmTranslatorVisitor::v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type
return true; return true;
} }
bool ArmTranslatorVisitor::v8_VLD_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t size, size_t align, Reg m) { bool TranslatorVisitor::v8_VLD_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t size, size_t align, Reg m) {
if (type == 0b1011 || type.Bits<2, 3>() == 0b11) { if (type == 0b1011 || type.Bits<2, 3>() == 0b11) {
return DecodeError(); return DecodeError();
} }
@ -178,7 +178,7 @@ bool ArmTranslatorVisitor::v8_VLD_multiple(bool D, Reg n, size_t Vd, Imm<4> type
return true; return true;
} }
bool ArmTranslatorVisitor::v8_VLD_all_lanes(bool D, Reg n, size_t Vd, size_t nn, size_t sz, bool T, bool a, Reg m) { bool TranslatorVisitor::v8_VLD_all_lanes(bool D, Reg n, size_t Vd, size_t nn, size_t sz, bool T, bool a, Reg m) {
const size_t nelem = nn + 1; const size_t nelem = nn + 1;
if (nelem == 1 && (sz == 0b11 || (sz == 0b00 && a))) { if (nelem == 1 && (sz == 0b11 || (sz == 0b00 && a))) {
@ -243,7 +243,7 @@ bool ArmTranslatorVisitor::v8_VLD_all_lanes(bool D, Reg n, size_t Vd, size_t nn,
return true; return true;
} }
bool ArmTranslatorVisitor::v8_VST_single(bool D, Reg n, size_t Vd, size_t sz, size_t nn, size_t index_align, Reg m) { bool TranslatorVisitor::v8_VST_single(bool D, Reg n, size_t Vd, size_t sz, size_t nn, size_t index_align, Reg m) {
const size_t nelem = nn + 1; const size_t nelem = nn + 1;
if (sz == 0b11) { if (sz == 0b11) {
@ -307,7 +307,7 @@ bool ArmTranslatorVisitor::v8_VST_single(bool D, Reg n, size_t Vd, size_t sz, si
return true; return true;
} }
bool ArmTranslatorVisitor::v8_VLD_single(bool D, Reg n, size_t Vd, size_t sz, size_t nn, size_t index_align, Reg m) { bool TranslatorVisitor::v8_VLD_single(bool D, Reg n, size_t Vd, size_t sz, size_t nn, size_t index_align, Reg m) {
const size_t nelem = nn + 1; const size_t nelem = nn + 1;
if (sz == 0b11) { if (sz == 0b11) {

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static bool TableLookup(ArmTranslatorVisitor& v, bool is_vtbl, bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) { static bool TableLookup(TranslatorVisitor& v, bool is_vtbl, bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) {
const size_t length = len + 1; const size_t length = len + 1;
const auto d = ToVector(false, Vd, D); const auto d = ToVector(false, Vd, D);
const auto m = ToVector(false, Vm, M); const auto m = ToVector(false, Vm, M);
@ -35,7 +35,7 @@ static bool TableLookup(ArmTranslatorVisitor& v, bool is_vtbl, bool D, size_t Vn
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -57,15 +57,15 @@ bool ArmTranslatorVisitor::asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VTBL(bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VTBL(bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) {
return TableLookup(*this, true, D, Vn, Vd, len, N, M, Vm); return TableLookup(*this, true, D, Vn, Vd, len, N, M, Vm);
} }
bool ArmTranslatorVisitor::asimd_VTBX(bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VTBX(bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) {
return TableLookup(*this, false, D, Vn, Vd, len, N, M, Vm); return TableLookup(*this, false, D, Vn, Vd, len, N, M, Vm);
} }
bool ArmTranslatorVisitor::asimd_VDUP_scalar(bool D, Imm<4> imm4, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VDUP_scalar(bool D, Imm<4> imm4, size_t Vd, bool Q, bool M, size_t Vm) {
if (Q && Common::Bit<0>(Vd)) { if (Q && Common::Bit<0>(Vd)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ArmTranslatorVisitor::asimd_VMOV_imm(Imm<1> a, bool D, Imm<1> b, Imm<1> c, Imm<1> d, size_t Vd, bool TranslatorVisitor::asimd_VMOV_imm(Imm<1> a, bool D, Imm<1> b, Imm<1> c, Imm<1> d, size_t Vd,
Imm<4> cmode, bool Q, bool op, Imm<1> e, Imm<1> f, Imm<1> g, Imm<1> h) { Imm<4> cmode, bool Q, bool op, Imm<1> e, Imm<1> f, Imm<1> g, Imm<1> h) {
if (Q && Common::Bit<0>(Vd)) { if (Q && Common::Bit<0>(Vd)) {
return UndefinedInstruction(); return UndefinedInstruction();

View file

@ -3,9 +3,9 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "common/bit_util.h" #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/impl/translate_arm.h" #include "common/bit_util.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
@ -28,7 +28,7 @@ enum class WidenBehaviour {
}; };
template <bool WithDst, typename Callable> template <bool WithDst, typename Callable>
bool BitwiseInstruction(ArmTranslatorVisitor& v, bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, Callable fn) { bool BitwiseInstruction(TranslatorVisitor& v, bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, Callable fn) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
} }
@ -54,7 +54,7 @@ bool BitwiseInstruction(ArmTranslatorVisitor& v, bool D, size_t Vn, size_t Vd, b
} }
template <typename Callable> template <typename Callable>
bool FloatingPointInstruction(ArmTranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, Callable fn) { bool FloatingPointInstruction(TranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, Callable fn) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
} }
@ -76,7 +76,7 @@ bool FloatingPointInstruction(ArmTranslatorVisitor& v, bool D, bool sz, size_t V
return true; return true;
} }
bool IntegerComparison(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, bool IntegerComparison(TranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm,
Comparison comparison) { Comparison comparison) {
if (sz == 0b11) { if (sz == 0b11) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
@ -112,7 +112,7 @@ bool IntegerComparison(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_
return true; return true;
} }
bool FloatComparison(ArmTranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, bool FloatComparison(TranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm,
Comparison comparison) { Comparison comparison) {
if (sz) { if (sz) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
@ -149,7 +149,7 @@ bool FloatComparison(ArmTranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t
return true; return true;
} }
bool AbsoluteDifference(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm, bool AbsoluteDifference(TranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm,
AccumulateBehavior accumulate) { AccumulateBehavior accumulate) {
if (sz == 0b11) { if (sz == 0b11) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
@ -182,7 +182,7 @@ bool AbsoluteDifference(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size
return true; return true;
} }
bool AbsoluteDifferenceLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm, bool AbsoluteDifferenceLong(TranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm,
AccumulateBehavior accumulate) { AccumulateBehavior accumulate) {
if (sz == 0b11) { if (sz == 0b11) {
return v.DecodeError(); return v.DecodeError();
@ -218,7 +218,7 @@ bool AbsoluteDifferenceLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz,
} }
template <typename Callable> template <typename Callable>
bool WideInstruction(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm, WidenBehaviour widen_behaviour, Callable fn) { bool WideInstruction(TranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm, WidenBehaviour widen_behaviour, Callable fn) {
const size_t esize = 8U << sz; const size_t esize = 8U << sz;
const bool widen_first = widen_behaviour == WidenBehaviour::Both; const bool widen_first = widen_behaviour == WidenBehaviour::Both;
@ -249,7 +249,7 @@ bool WideInstruction(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_t
// ASIMD Three registers of the same length // ASIMD Three registers of the same length
bool ArmTranslatorVisitor::asimd_VHADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VHADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -271,7 +271,7 @@ bool ArmTranslatorVisitor::asimd_VHADD(bool U, bool D, size_t sz, size_t Vn, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -293,7 +293,7 @@ bool ArmTranslatorVisitor::asimd_VQADD(bool U, bool D, size_t sz, size_t Vn, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VRHADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRHADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -315,55 +315,55 @@ bool ArmTranslatorVisitor::asimd_VRHADD(bool U, bool D, size_t sz, size_t Vn, si
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VAND_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VAND_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) {
return ir.VectorAnd(reg_n, reg_m); return ir.VectorAnd(reg_n, reg_m);
}); });
} }
bool ArmTranslatorVisitor::asimd_VBIC_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VBIC_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) {
return ir.VectorAnd(reg_n, ir.VectorNot(reg_m)); return ir.VectorAnd(reg_n, ir.VectorNot(reg_m));
}); });
} }
bool ArmTranslatorVisitor::asimd_VORR_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VORR_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) {
return ir.VectorOr(reg_n, reg_m); return ir.VectorOr(reg_n, reg_m);
}); });
} }
bool ArmTranslatorVisitor::asimd_VORN_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VORN_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) {
return ir.VectorOr(reg_n, ir.VectorNot(reg_m)); return ir.VectorOr(reg_n, ir.VectorNot(reg_m));
}); });
} }
bool ArmTranslatorVisitor::asimd_VEOR_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VEOR_reg(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<false>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_n, const auto& reg_m) {
return ir.VectorEor(reg_n, reg_m); return ir.VectorEor(reg_n, reg_m);
}); });
} }
bool ArmTranslatorVisitor::asimd_VBSL(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VBSL(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<true>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<true>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
return ir.VectorOr(ir.VectorAnd(reg_n, reg_d), ir.VectorAnd(reg_m, ir.VectorNot(reg_d))); return ir.VectorOr(ir.VectorAnd(reg_n, reg_d), ir.VectorAnd(reg_m, ir.VectorNot(reg_d)));
}); });
} }
bool ArmTranslatorVisitor::asimd_VBIT(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VBIT(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<true>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<true>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
return ir.VectorOr(ir.VectorAnd(reg_n, reg_m), ir.VectorAnd(reg_d, ir.VectorNot(reg_m))); return ir.VectorOr(ir.VectorAnd(reg_n, reg_m), ir.VectorAnd(reg_d, ir.VectorNot(reg_m)));
}); });
} }
bool ArmTranslatorVisitor::asimd_VBIF(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VBIF(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return BitwiseInstruction<true>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return BitwiseInstruction<true>(*this, D, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
return ir.VectorOr(ir.VectorAnd(reg_d, reg_m), ir.VectorAnd(reg_n, ir.VectorNot(reg_m))); return ir.VectorOr(ir.VectorAnd(reg_d, reg_m), ir.VectorAnd(reg_n, ir.VectorNot(reg_m)));
}); });
} }
bool ArmTranslatorVisitor::asimd_VHSUB(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VHSUB(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -385,7 +385,7 @@ bool ArmTranslatorVisitor::asimd_VHSUB(bool U, bool D, size_t sz, size_t Vn, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQSUB(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQSUB(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -407,23 +407,23 @@ bool ArmTranslatorVisitor::asimd_VQSUB(bool U, bool D, size_t sz, size_t Vn, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCGT_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCGT_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return IntegerComparison(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GT); return IntegerComparison(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GT);
} }
bool ArmTranslatorVisitor::asimd_VCGE_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCGE_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return IntegerComparison(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GE); return IntegerComparison(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GE);
} }
bool ArmTranslatorVisitor::asimd_VABD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VABD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return AbsoluteDifference(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, AccumulateBehavior::None); return AbsoluteDifference(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, AccumulateBehavior::None);
} }
bool ArmTranslatorVisitor::asimd_VABA(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VABA(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return AbsoluteDifference(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, AccumulateBehavior::Accumulate); return AbsoluteDifference(*this, U, D, sz, Vn, Vd, N, Q, M, Vm, AccumulateBehavior::Accumulate);
} }
bool ArmTranslatorVisitor::asimd_VADD_int(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VADD_int(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -441,7 +441,7 @@ bool ArmTranslatorVisitor::asimd_VADD_int(bool D, size_t sz, size_t Vn, size_t V
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSUB_int(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSUB_int(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -459,7 +459,7 @@ bool ArmTranslatorVisitor::asimd_VSUB_int(bool D, size_t sz, size_t Vn, size_t V
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSHL_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSHL_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -478,7 +478,7 @@ bool ArmTranslatorVisitor::asimd_VSHL_reg(bool U, bool D, size_t sz, size_t Vn,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQSHL_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQSHL_reg(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -497,7 +497,7 @@ bool ArmTranslatorVisitor::asimd_VQSHL_reg(bool U, bool D, size_t sz, size_t Vn,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VRSHL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRSHL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -516,7 +516,7 @@ bool ArmTranslatorVisitor::asimd_VRSHL(bool U, bool D, size_t sz, size_t Vn, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VMAX(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, bool op, size_t Vm) { bool TranslatorVisitor::asimd_VMAX(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, bool op, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -546,7 +546,7 @@ bool ArmTranslatorVisitor::asimd_VMAX(bool U, bool D, size_t sz, size_t Vn, size
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VTST(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VTST(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -569,11 +569,11 @@ bool ArmTranslatorVisitor::asimd_VTST(bool D, size_t sz, size_t Vn, size_t Vd, b
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCEQ_reg(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCEQ_reg(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return IntegerComparison(*this, false, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::EQ); return IntegerComparison(*this, false, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::EQ);
} }
bool ArmTranslatorVisitor::asimd_VMLA(bool op, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMLA(bool op, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -598,7 +598,7 @@ bool ArmTranslatorVisitor::asimd_VMLA(bool op, bool D, size_t sz, size_t Vn, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VMUL(bool P, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMUL(bool P, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (sz == 0b11 || (P && sz != 0b00)) { if (sz == 0b11 || (P && sz != 0b00)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -621,7 +621,7 @@ bool ArmTranslatorVisitor::asimd_VMUL(bool P, bool D, size_t sz, size_t Vn, size
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VPMAX_int(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, bool op, size_t Vm) { bool TranslatorVisitor::asimd_VPMAX_int(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, bool op, size_t Vm) {
if (sz == 0b11 || Q) { if (sz == 0b11 || Q) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -651,7 +651,7 @@ bool ArmTranslatorVisitor::asimd_VPMAX_int(bool U, bool D, size_t sz, size_t Vn,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQDMULH(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQDMULH(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -673,7 +673,7 @@ bool ArmTranslatorVisitor::asimd_VQDMULH(bool D, size_t sz, size_t Vn, size_t Vd
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQRDMULH(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQRDMULH(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -696,7 +696,7 @@ bool ArmTranslatorVisitor::asimd_VQRDMULH(bool D, size_t sz, size_t Vn, size_t V
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VPADD(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VPADD(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q || sz == 0b11) { if (Q || sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -714,31 +714,31 @@ bool ArmTranslatorVisitor::asimd_VPADD(bool D, size_t sz, size_t Vn, size_t Vd,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VFMA(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VFMA(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorMulAdd(32, reg_d, reg_n, reg_m, false); return ir.FPVectorMulAdd(32, reg_d, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VFMS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VFMS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorMulAdd(32, reg_d, ir.FPVectorNeg(32, reg_n), reg_m, false); return ir.FPVectorMulAdd(32, reg_d, ir.FPVectorNeg(32, reg_n), reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VADD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VADD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorAdd(32, reg_n, reg_m, false); return ir.FPVectorAdd(32, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VSUB_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSUB_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorSub(32, reg_n, reg_m, false); return ir.FPVectorSub(32, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VPADD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VPADD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q) { if (Q) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -747,62 +747,62 @@ bool ArmTranslatorVisitor::asimd_VPADD_float(bool D, bool sz, size_t Vn, size_t
}); });
} }
bool ArmTranslatorVisitor::asimd_VABD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VABD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorAbs(32, ir.FPVectorSub(32, reg_n, reg_m, false)); return ir.FPVectorAbs(32, ir.FPVectorSub(32, reg_n, reg_m, false));
}); });
} }
bool ArmTranslatorVisitor::asimd_VMLA_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMLA_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
const auto product = ir.FPVectorMul(32, reg_n, reg_m, false); const auto product = ir.FPVectorMul(32, reg_n, reg_m, false);
return ir.FPVectorAdd(32, reg_d, product, false); return ir.FPVectorAdd(32, reg_d, product, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VMLS_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMLS_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto& reg_d, const auto& reg_n, const auto& reg_m) {
const auto product = ir.FPVectorMul(32, reg_n, reg_m, false); const auto product = ir.FPVectorMul(32, reg_n, reg_m, false);
return ir.FPVectorAdd(32, reg_d, ir.FPVectorNeg(32, product), false); return ir.FPVectorAdd(32, reg_d, ir.FPVectorNeg(32, product), false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VMUL_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMUL_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorMul(32, reg_n, reg_m, false); return ir.FPVectorMul(32, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VCEQ_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCEQ_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::EQ); return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::EQ);
} }
bool ArmTranslatorVisitor::asimd_VCGE_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCGE_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GE); return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GE);
} }
bool ArmTranslatorVisitor::asimd_VCGT_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCGT_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GT); return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GT);
} }
bool ArmTranslatorVisitor::asimd_VACGE(bool D, bool op, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VACGE(bool D, bool op, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
const auto comparison = op ? Comparison::AbsoluteGT : Comparison::AbsoluteGE; const auto comparison = op ? Comparison::AbsoluteGT : Comparison::AbsoluteGE;
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, comparison); return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, comparison);
} }
bool ArmTranslatorVisitor::asimd_VMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorMax(32, reg_n, reg_m, false); return ir.FPVectorMax(32, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorMin(32, reg_n, reg_m, false); return ir.FPVectorMin(32, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VPMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VPMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q) { if (Q) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -813,7 +813,7 @@ bool ArmTranslatorVisitor::asimd_VPMAX_float(bool D, bool sz, size_t Vn, size_t
}); });
} }
bool ArmTranslatorVisitor::asimd_VPMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VPMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
if (Q) { if (Q) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -824,13 +824,13 @@ bool ArmTranslatorVisitor::asimd_VPMIN_float(bool D, bool sz, size_t Vn, size_t
}); });
} }
bool ArmTranslatorVisitor::asimd_VRECPS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRECPS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorRecipStepFused(32, reg_n, reg_m, false); return ir.FPVectorRecipStepFused(32, reg_n, reg_m, false);
}); });
} }
bool ArmTranslatorVisitor::asimd_VRSQRTS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRSQRTS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
return ir.FPVectorRSqrtStepFused(32, reg_n, reg_m, false); return ir.FPVectorRSqrtStepFused(32, reg_n, reg_m, false);
}); });
@ -838,27 +838,27 @@ bool ArmTranslatorVisitor::asimd_VRSQRTS(bool D, bool sz, size_t Vn, size_t Vd,
// ASIMD Three registers of different length // ASIMD Three registers of different length
bool ArmTranslatorVisitor::asimd_VADDL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VADDL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) {
return WideInstruction(*this, U, D, sz, Vn, Vd, N, M, Vm, op ? WidenBehaviour::Second : WidenBehaviour::Both, [this](size_t esize, const auto&, const auto& reg_n, const auto& reg_m) { return WideInstruction(*this, U, D, sz, Vn, Vd, N, M, Vm, op ? WidenBehaviour::Second : WidenBehaviour::Both, [this](size_t esize, const auto&, const auto& reg_n, const auto& reg_m) {
return ir.VectorAdd(esize, reg_n, reg_m); return ir.VectorAdd(esize, reg_n, reg_m);
}); });
} }
bool ArmTranslatorVisitor::asimd_VSUBL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSUBL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) {
return WideInstruction(*this, U, D, sz, Vn, Vd, N, M, Vm, op ? WidenBehaviour::Second : WidenBehaviour::Both, [this](size_t esize, const auto&, const auto& reg_n, const auto& reg_m) { return WideInstruction(*this, U, D, sz, Vn, Vd, N, M, Vm, op ? WidenBehaviour::Second : WidenBehaviour::Both, [this](size_t esize, const auto&, const auto& reg_n, const auto& reg_m) {
return ir.VectorSub(esize, reg_n, reg_m); return ir.VectorSub(esize, reg_n, reg_m);
}); });
} }
bool ArmTranslatorVisitor::asimd_VABAL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VABAL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
return AbsoluteDifferenceLong(*this, U, D, sz, Vn, Vd, N, M, Vm, AccumulateBehavior::Accumulate); return AbsoluteDifferenceLong(*this, U, D, sz, Vn, Vd, N, M, Vm, AccumulateBehavior::Accumulate);
} }
bool ArmTranslatorVisitor::asimd_VABDL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VABDL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
return AbsoluteDifferenceLong(*this, U, D, sz, Vn, Vd, N, M, Vm, AccumulateBehavior::None); return AbsoluteDifferenceLong(*this, U, D, sz, Vn, Vd, N, M, Vm, AccumulateBehavior::None);
} }
bool ArmTranslatorVisitor::asimd_VMLAL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMLAL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) {
return WideInstruction(*this, U, D, sz, Vn, Vd, N, M, Vm, WidenBehaviour::Both, [this, op](size_t esize, const auto& reg_d, const auto& reg_n, const auto& reg_m) { return WideInstruction(*this, U, D, sz, Vn, Vd, N, M, Vm, WidenBehaviour::Both, [this, op](size_t esize, const auto& reg_d, const auto& reg_n, const auto& reg_m) {
const auto multiply = ir.VectorMultiply(esize, reg_n, reg_m); const auto multiply = ir.VectorMultiply(esize, reg_n, reg_m);
return op ? ir.VectorSub(esize, reg_d, multiply) return op ? ir.VectorSub(esize, reg_d, multiply)
@ -866,7 +866,7 @@ bool ArmTranslatorVisitor::asimd_VMLAL(bool U, bool D, size_t sz, size_t Vn, siz
}); });
} }
bool ArmTranslatorVisitor::asimd_VMULL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool P, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMULL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool P, bool N, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return DecodeError(); return DecodeError();
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "common/bit_util.h" #include "frontend/A32/translate/impl/translate.h"
#include <array> #include <array>
#include "frontend/A32/translate/impl/translate_arm.h" #include "common/bit_util.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
@ -19,7 +19,8 @@ enum class Comparison {
LT, LT,
}; };
bool CompareWithZero(ArmTranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm, Comparison type) { bool CompareWithZero(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm,
Comparison type) {
if (sz == 0b11 || (F && sz != 0b10)) { if (sz == 0b11 || (F && sz != 0b10)) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
} }
@ -72,7 +73,7 @@ enum class AccumulateBehavior {
Accumulate, Accumulate,
}; };
bool PairedAddOperation(ArmTranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm, bool PairedAddOperation(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm,
AccumulateBehavior accumulate) { AccumulateBehavior accumulate) {
if (sz == 0b11) { if (sz == 0b11) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
@ -105,7 +106,7 @@ bool PairedAddOperation(ArmTranslatorVisitor& v, bool D, size_t sz, size_t Vd, b
} // Anonymous namespace } // Anonymous namespace
bool ArmTranslatorVisitor::asimd_VREV(bool D, size_t sz, size_t Vd, size_t op, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VREV(bool D, size_t sz, size_t Vd, size_t op, bool Q, bool M, size_t Vm) {
if (op + sz >= 3) { if (op + sz >= 3) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -165,11 +166,11 @@ bool ArmTranslatorVisitor::asimd_VREV(bool D, size_t sz, size_t Vd, size_t op, b
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VPADDL(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VPADDL(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) {
return PairedAddOperation(*this, D, sz, Vd, op, Q, M, Vm, AccumulateBehavior::None); return PairedAddOperation(*this, D, sz, Vd, op, Q, M, Vm, AccumulateBehavior::None);
} }
bool ArmTranslatorVisitor::v8_AESD(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::v8_AESD(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) { if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -184,7 +185,7 @@ bool ArmTranslatorVisitor::v8_AESD(bool D, size_t sz, size_t Vd, bool M, size_t
return true; return true;
} }
bool ArmTranslatorVisitor::v8_AESE(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::v8_AESE(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) { if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -199,7 +200,7 @@ bool ArmTranslatorVisitor::v8_AESE(bool D, size_t sz, size_t Vd, bool M, size_t
return true; return true;
} }
bool ArmTranslatorVisitor::v8_AESIMC(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::v8_AESIMC(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) { if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -213,7 +214,7 @@ bool ArmTranslatorVisitor::v8_AESIMC(bool D, size_t sz, size_t Vd, bool M, size_
return true; return true;
} }
bool ArmTranslatorVisitor::v8_AESMC(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::v8_AESMC(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) { if (sz != 0b00 || Common::Bit<0>(Vd) || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -227,7 +228,7 @@ bool ArmTranslatorVisitor::v8_AESMC(bool D, size_t sz, size_t Vd, bool M, size_t
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCLS(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCLS(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -251,7 +252,7 @@ bool ArmTranslatorVisitor::asimd_VCLS(bool D, size_t sz, size_t Vd, bool Q, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCLZ(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCLZ(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -273,7 +274,7 @@ bool ArmTranslatorVisitor::asimd_VCLZ(bool D, size_t sz, size_t Vd, bool Q, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCNT(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCNT(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz != 0b00) { if (sz != 0b00) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -291,7 +292,7 @@ bool ArmTranslatorVisitor::asimd_VCNT(bool D, size_t sz, size_t Vd, bool Q, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VMVN_reg(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMVN_reg(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz != 0b00) { if (sz != 0b00) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -310,11 +311,11 @@ bool ArmTranslatorVisitor::asimd_VMVN_reg(bool D, size_t sz, size_t Vd, bool Q,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VPADAL(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VPADAL(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) {
return PairedAddOperation(*this, D, sz, Vd, op, Q, M, Vm, AccumulateBehavior::Accumulate); return PairedAddOperation(*this, D, sz, Vd, op, Q, M, Vm, AccumulateBehavior::Accumulate);
} }
bool ArmTranslatorVisitor::asimd_VQABS(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQABS(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -334,7 +335,7 @@ bool ArmTranslatorVisitor::asimd_VQABS(bool D, size_t sz, size_t Vd, bool Q, boo
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQNEG(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQNEG(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -354,27 +355,27 @@ bool ArmTranslatorVisitor::asimd_VQNEG(bool D, size_t sz, size_t Vd, bool Q, boo
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCGT_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCGT_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::GT); return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::GT);
} }
bool ArmTranslatorVisitor::asimd_VCGE_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCGE_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::GE); return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::GE);
} }
bool ArmTranslatorVisitor::asimd_VCEQ_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCEQ_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::EQ); return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::EQ);
} }
bool ArmTranslatorVisitor::asimd_VCLE_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCLE_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::LE); return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::LE);
} }
bool ArmTranslatorVisitor::asimd_VCLT_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCLT_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::LT); return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::LT);
} }
bool ArmTranslatorVisitor::asimd_VABS(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VABS(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
if (sz == 0b11 || (F && sz != 0b10)) { if (sz == 0b11 || (F && sz != 0b10)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -400,7 +401,7 @@ bool ArmTranslatorVisitor::asimd_VABS(bool D, size_t sz, size_t Vd, bool F, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VNEG(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VNEG(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
if (sz == 0b11 || (F && sz != 0b10)) { if (sz == 0b11 || (F && sz != 0b10)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -426,7 +427,7 @@ bool ArmTranslatorVisitor::asimd_VNEG(bool D, size_t sz, size_t Vd, bool F, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSWP(bool D, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSWP(bool D, size_t Vd, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -455,7 +456,7 @@ bool ArmTranslatorVisitor::asimd_VSWP(bool D, size_t Vd, bool Q, bool M, size_t
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VTRN(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VTRN(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -482,7 +483,7 @@ bool ArmTranslatorVisitor::asimd_VTRN(bool D, size_t sz, size_t Vd, bool Q, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VUZP(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VUZP(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11 || (!Q && sz == 0b10)) { if (sz == 0b11 || (!Q && sz == 0b10)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -514,7 +515,7 @@ bool ArmTranslatorVisitor::asimd_VUZP(bool D, size_t sz, size_t Vd, bool Q, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VZIP(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VZIP(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm) {
if (sz == 0b11 || (!Q && sz == 0b10)) { if (sz == 0b11 || (!Q && sz == 0b10)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -549,7 +550,7 @@ bool ArmTranslatorVisitor::asimd_VZIP(bool D, size_t sz, size_t Vd, bool Q, bool
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VMOVN(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMOVN(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz == 0b11 || Common::Bit<0>(Vm)) { if (sz == 0b11 || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -564,7 +565,7 @@ bool ArmTranslatorVisitor::asimd_VMOVN(bool D, size_t sz, size_t Vd, bool M, siz
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQMOVUN(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQMOVUN(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz == 0b11 || Common::Bit<0>(Vm)) { if (sz == 0b11 || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -579,7 +580,7 @@ bool ArmTranslatorVisitor::asimd_VQMOVUN(bool D, size_t sz, size_t Vd, bool M, s
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQMOVN(bool D, size_t sz, size_t Vd, bool op, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQMOVN(bool D, size_t sz, size_t Vd, bool op, bool M, size_t Vm) {
if (sz == 0b11 || Common::Bit<0>(Vm)) { if (sz == 0b11 || Common::Bit<0>(Vm)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -595,7 +596,7 @@ bool ArmTranslatorVisitor::asimd_VQMOVN(bool D, size_t sz, size_t Vd, bool op, b
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSHLL_max(bool D, size_t sz, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSHLL_max(bool D, size_t sz, size_t Vd, bool M, size_t Vm) {
if (sz == 0b11 || Common::Bit<0>(Vd)) { if (sz == 0b11 || Common::Bit<0>(Vd)) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -610,7 +611,7 @@ bool ArmTranslatorVisitor::asimd_VSHLL_max(bool D, size_t sz, size_t Vd, bool M,
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -636,7 +637,7 @@ bool ArmTranslatorVisitor::asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bo
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VRSQRTE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRSQRTE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -662,7 +663,7 @@ bool ArmTranslatorVisitor::asimd_VRSQRTE(bool D, size_t sz, size_t Vd, bool F, b
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCVT_integer(bool D, size_t sz, size_t Vd, bool op, bool U, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCVT_integer(bool D, size_t sz, size_t Vd, bool op, bool U, bool Q, bool M, size_t Vm) {
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) { if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vm))) {
return UndefinedInstruction(); return UndefinedInstruction();
} }

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include <utility> #include <utility>
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
std::pair<ExtReg, size_t> GetScalarLocation(size_t esize, bool M, size_t Vm) { std::pair<ExtReg, size_t> GetScalarLocation(size_t esize, bool M, size_t Vm) {
@ -29,7 +29,7 @@ enum class Rounding {
Round, Round,
}; };
bool ScalarMultiply(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm, bool ScalarMultiply(TranslatorVisitor& v, bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm,
MultiplyBehavior multiply) { MultiplyBehavior multiply) {
if (sz == 0b11) { if (sz == 0b11) {
return v.DecodeError(); return v.DecodeError();
@ -72,7 +72,8 @@ bool ScalarMultiply(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz, size_t V
return true; return true;
} }
bool ScalarMultiplyLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm, MultiplyBehavior multiply) { bool ScalarMultiplyLong(TranslatorVisitor& v, bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm,
MultiplyBehavior multiply) {
if (sz == 0b11) { if (sz == 0b11) {
return v.DecodeError(); return v.DecodeError();
} }
@ -109,7 +110,7 @@ bool ScalarMultiplyLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size
return true; return true;
} }
bool ScalarMultiplyReturnHigh(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm, bool ScalarMultiplyReturnHigh(TranslatorVisitor& v, bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm,
Rounding round) { Rounding round) {
if (sz == 0b11) { if (sz == 0b11) {
return v.DecodeError(); return v.DecodeError();
@ -146,27 +147,27 @@ bool ScalarMultiplyReturnHigh(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz
} }
} // Anonymous namespace } // Anonymous namespace
bool ArmTranslatorVisitor::asimd_VMLA_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool F, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMLA_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool F, bool N, bool M, size_t Vm) {
const auto behavior = op ? MultiplyBehavior::MultiplySubtract const auto behavior = op ? MultiplyBehavior::MultiplySubtract
: MultiplyBehavior::MultiplyAccumulate; : MultiplyBehavior::MultiplyAccumulate;
return ScalarMultiply(*this, Q, D, sz, Vn, Vd, F, N, M, Vm, behavior); return ScalarMultiply(*this, Q, D, sz, Vn, Vd, F, N, M, Vm, behavior);
} }
bool ArmTranslatorVisitor::asimd_VMLAL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMLAL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) {
const auto behavior = op ? MultiplyBehavior::MultiplySubtract const auto behavior = op ? MultiplyBehavior::MultiplySubtract
: MultiplyBehavior::MultiplyAccumulate; : MultiplyBehavior::MultiplyAccumulate;
return ScalarMultiplyLong(*this, U, D, sz, Vn, Vd, N, M, Vm, behavior); return ScalarMultiplyLong(*this, U, D, sz, Vn, Vd, N, M, Vm, behavior);
} }
bool ArmTranslatorVisitor::asimd_VMUL_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMUL_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm) {
return ScalarMultiply(*this, Q, D, sz, Vn, Vd, F, N, M, Vm, MultiplyBehavior::Multiply); return ScalarMultiply(*this, Q, D, sz, Vn, Vd, F, N, M, Vm, MultiplyBehavior::Multiply);
} }
bool ArmTranslatorVisitor::asimd_VMULL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VMULL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
return ScalarMultiplyLong(*this, U, D, sz, Vn, Vd, N, M, Vm, MultiplyBehavior::Multiply); return ScalarMultiplyLong(*this, U, D, sz, Vn, Vd, N, M, Vm, MultiplyBehavior::Multiply);
} }
bool ArmTranslatorVisitor::asimd_VQDMULL_scalar(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQDMULL_scalar(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
if (sz == 0b11) { if (sz == 0b11) {
return DecodeError(); return DecodeError();
} }
@ -189,11 +190,11 @@ bool ArmTranslatorVisitor::asimd_VQDMULL_scalar(bool D, size_t sz, size_t Vn, si
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
return ScalarMultiplyReturnHigh(*this, Q, D, sz, Vn, Vd, N, M, Vm, Rounding::None); return ScalarMultiplyReturnHigh(*this, Q, D, sz, Vn, Vd, N, M, Vm, Rounding::None);
} }
bool ArmTranslatorVisitor::asimd_VQRDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQRDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
return ScalarMultiplyReturnHigh(*this, Q, D, sz, Vn, Vd, N, M, Vm, Rounding::Round); return ScalarMultiplyReturnHigh(*this, Q, D, sz, Vn, Vd, N, M, Vm, Rounding::Round);
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
enum class Accumulating { enum class Accumulating {
@ -31,7 +31,7 @@ enum class Signedness {
Unsigned Unsigned
}; };
IR::U128 PerformRoundingCorrection(ArmTranslatorVisitor& v, size_t esize, u64 round_value, IR::U128 original, IR::U128 shifted) { IR::U128 PerformRoundingCorrection(TranslatorVisitor& v, size_t esize, u64 round_value, IR::U128 original, IR::U128 shifted) {
const auto round_const = v.ir.VectorBroadcast(esize, v.I(esize, round_value)); const auto round_const = v.ir.VectorBroadcast(esize, v.I(esize, round_value));
const auto round_correction = v.ir.VectorEqual(esize, v.ir.VectorAnd(original, round_const), round_const); const auto round_correction = v.ir.VectorEqual(esize, v.ir.VectorAnd(original, round_const), round_const);
return v.ir.VectorSub(esize, shifted, round_correction); return v.ir.VectorSub(esize, shifted, round_correction);
@ -57,7 +57,7 @@ std::pair<size_t, size_t> ElementSizeAndShiftAmount(bool right_shift, bool L, si
} }
} }
bool ShiftRight(ArmTranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm, bool ShiftRight(TranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm,
Accumulating accumulate, Rounding rounding) { Accumulating accumulate, Rounding rounding) {
if (!L && Common::Bits<3, 5>(imm6) == 0) { if (!L && Common::Bits<3, 5>(imm6) == 0) {
return v.DecodeError(); return v.DecodeError();
@ -89,7 +89,7 @@ bool ShiftRight(ArmTranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd,
return true; return true;
} }
bool ShiftRightNarrowing(ArmTranslatorVisitor& v, bool D, size_t imm6, size_t Vd, bool M, size_t Vm, bool ShiftRightNarrowing(TranslatorVisitor& v, bool D, size_t imm6, size_t Vd, bool M, size_t Vm,
Rounding rounding, Narrowing narrowing, Signedness signedness) { Rounding rounding, Narrowing narrowing, Signedness signedness) {
if (Common::Bits<3, 5>(imm6) == 0) { if (Common::Bits<3, 5>(imm6) == 0) {
return v.DecodeError(); return v.DecodeError();
@ -140,27 +140,27 @@ bool ShiftRightNarrowing(ArmTranslatorVisitor& v, bool D, size_t imm6, size_t Vd
} }
} // Anonymous namespace } // Anonymous namespace
bool ArmTranslatorVisitor::asimd_SHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_SHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm, return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
Accumulating::None, Rounding::None); Accumulating::None, Rounding::None);
} }
bool ArmTranslatorVisitor::asimd_SRA(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_SRA(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm, return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
Accumulating::Accumulate, Rounding::None); Accumulating::Accumulate, Rounding::None);
} }
bool ArmTranslatorVisitor::asimd_VRSHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRSHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm, return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
Accumulating::None, Rounding::Round); Accumulating::None, Rounding::Round);
} }
bool ArmTranslatorVisitor::asimd_VRSRA(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRSRA(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm, return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
Accumulating::Accumulate, Rounding::Round); Accumulating::Accumulate, Rounding::Round);
} }
bool ArmTranslatorVisitor::asimd_VSRI(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSRI(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
if (!L && Common::Bits<3, 5>(imm6) == 0) { if (!L && Common::Bits<3, 5>(imm6) == 0) {
return DecodeError(); return DecodeError();
} }
@ -186,7 +186,7 @@ bool ArmTranslatorVisitor::asimd_VSRI(bool D, size_t imm6, size_t Vd, bool L, bo
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSLI(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSLI(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
if (!L && Common::Bits<3, 5>(imm6) == 0) { if (!L && Common::Bits<3, 5>(imm6) == 0) {
return DecodeError(); return DecodeError();
} }
@ -212,7 +212,7 @@ bool ArmTranslatorVisitor::asimd_VSLI(bool D, size_t imm6, size_t Vd, bool L, bo
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VQSHL(bool U, bool D, size_t imm6, size_t Vd, bool op, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQSHL(bool U, bool D, size_t imm6, size_t Vd, bool op, bool L, bool Q, bool M, size_t Vm) {
if (!L && Common::Bits<3, 5>(imm6) == 0) { if (!L && Common::Bits<3, 5>(imm6) == 0) {
return DecodeError(); return DecodeError();
} }
@ -250,7 +250,7 @@ bool ArmTranslatorVisitor::asimd_VQSHL(bool U, bool D, size_t imm6, size_t Vd, b
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSHL(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSHL(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
if (!L && Common::Bits<3, 5>(imm6) == 0) { if (!L && Common::Bits<3, 5>(imm6) == 0) {
return DecodeError(); return DecodeError();
} }
@ -270,37 +270,37 @@ bool ArmTranslatorVisitor::asimd_VSHL(bool D, size_t imm6, size_t Vd, bool L, bo
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VSHRN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSHRN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm, return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
Rounding::None, Narrowing::Truncation, Signedness::Unsigned); Rounding::None, Narrowing::Truncation, Signedness::Unsigned);
} }
bool ArmTranslatorVisitor::asimd_VRSHRN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VRSHRN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm, return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
Rounding::Round, Narrowing::Truncation, Signedness::Unsigned); Rounding::Round, Narrowing::Truncation, Signedness::Unsigned);
} }
bool ArmTranslatorVisitor::asimd_VQRSHRUN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQRSHRUN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm, return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
Rounding::Round, Narrowing::SaturateToUnsigned, Signedness::Signed); Rounding::Round, Narrowing::SaturateToUnsigned, Signedness::Signed);
} }
bool ArmTranslatorVisitor::asimd_VQSHRUN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQSHRUN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm, return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
Rounding::None, Narrowing::SaturateToUnsigned, Signedness::Signed); Rounding::None, Narrowing::SaturateToUnsigned, Signedness::Signed);
} }
bool ArmTranslatorVisitor::asimd_VQSHRN(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQSHRN(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm, return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
Rounding::None, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed); Rounding::None, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed);
} }
bool ArmTranslatorVisitor::asimd_VQRSHRN(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VQRSHRN(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm, return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
Rounding::Round, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed); Rounding::Round, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed);
} }
bool ArmTranslatorVisitor::asimd_VSHLL(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VSHLL(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
if (Common::Bits<3, 5>(imm6) == 0) { if (Common::Bits<3, 5>(imm6) == 0) {
return DecodeError(); return DecodeError();
} }
@ -322,7 +322,7 @@ bool ArmTranslatorVisitor::asimd_VSHLL(bool U, bool D, size_t imm6, size_t Vd, b
return true; return true;
} }
bool ArmTranslatorVisitor::asimd_VCVT_fixed(bool U, bool D, size_t imm6, size_t Vd, bool to_fixed, bool Q, bool M, size_t Vm) { bool TranslatorVisitor::asimd_VCVT_fixed(bool U, bool D, size_t imm6, size_t Vd, bool to_fixed, bool Q, bool M, size_t Vm) {
if (Common::Bits<3, 5>(imm6) == 0) { if (Common::Bits<3, 5>(imm6) == 0) {
return DecodeError(); return DecodeError();
} }

View file

@ -3,21 +3,21 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ArmTranslatorVisitor::arm_DMB([[maybe_unused]] Imm<4> option) { bool TranslatorVisitor::arm_DMB(Imm<4> /*option*/) {
ir.DataMemoryBarrier(); ir.DataMemoryBarrier();
return true; return true;
} }
bool ArmTranslatorVisitor::arm_DSB([[maybe_unused]] Imm<4> option) { bool TranslatorVisitor::arm_DSB(Imm<4> /*option*/) {
ir.DataSynchronizationBarrier(); ir.DataSynchronizationBarrier();
return true; return true;
} }
bool ArmTranslatorVisitor::arm_ISB([[maybe_unused]] Imm<4> option) { bool TranslatorVisitor::arm_ISB(Imm<4> /*option*/) {
ir.InstructionSynchronizationBarrier(); ir.InstructionSynchronizationBarrier();
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4)); ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
ir.SetTerm(IR::Term::ReturnToDispatch{}); ir.SetTerm(IR::Term::ReturnToDispatch{});

View file

@ -3,15 +3,15 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "common/bit_util.h" #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/impl/translate_arm.h" #include "common/bit_util.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// B <label> // B <label>
bool ArmTranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) { bool TranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -22,8 +22,8 @@ bool ArmTranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) {
} }
// BL <label> // BL <label>
bool ArmTranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) { bool TranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -37,7 +37,7 @@ bool ArmTranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) {
} }
// BLX <label> // BLX <label>
bool ArmTranslatorVisitor::arm_BLX_imm(bool H, Imm<24> imm24) { bool TranslatorVisitor::arm_BLX_imm(bool H, Imm<24> imm24) {
ir.PushRSB(ir.current_location.AdvancePC(4)); ir.PushRSB(ir.current_location.AdvancePC(4));
ir.SetRegister(Reg::LR, ir.Imm32(ir.current_location.PC() + 4)); ir.SetRegister(Reg::LR, ir.Imm32(ir.current_location.PC() + 4));
@ -48,12 +48,12 @@ bool ArmTranslatorVisitor::arm_BLX_imm(bool H, Imm<24> imm24) {
} }
// BLX <Rm> // BLX <Rm>
bool ArmTranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) { bool TranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) {
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -65,8 +65,8 @@ bool ArmTranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) {
} }
// BX <Rm> // BX <Rm>
bool ArmTranslatorVisitor::arm_BX(Cond cond, Reg m) { bool TranslatorVisitor::arm_BX(Cond cond, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -80,7 +80,7 @@ bool ArmTranslatorVisitor::arm_BX(Cond cond, Reg m) {
return false; return false;
} }
bool ArmTranslatorVisitor::arm_BXJ(Cond cond, Reg m) { bool TranslatorVisitor::arm_BXJ(Cond cond, Reg m) {
// Jazelle not supported // Jazelle not supported
return arm_BX(cond, m); return arm_BX(cond, m);
} }

View file

@ -3,19 +3,19 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// CDP{2} <coproc_no>, #<opc1>, <CRd>, <CRn>, <CRm>, #<opc2> // CDP{2} <coproc_no>, #<opc1>, <CRd>, <CRn>, <CRm>, #<opc2>
bool ArmTranslatorVisitor::arm_CDP(Cond cond, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm) { bool TranslatorVisitor::arm_CDP(Cond cond, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm) {
if ((coproc_no & 0b1110) == 0b1010) { if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
} }
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2); ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2);
} }
return true; return true;
@ -24,7 +24,7 @@ bool ArmTranslatorVisitor::arm_CDP(Cond cond, size_t opc1, CoprocReg CRn, Coproc
// LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>, #+/-<imm32>]{!} // LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>, #+/-<imm32>]{!}
// LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>], #+/-<imm32> // LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>], #+/-<imm32>
// LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>], <imm8> // LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>], <imm8>
bool ArmTranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8) { bool TranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8) {
if (!p && !u && !d && !w) { if (!p && !u && !d && !w) {
return arm_UDF(); return arm_UDF();
} }
@ -35,7 +35,7 @@ bool ArmTranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Re
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const bool index = p; const bool index = p;
const bool add = u; const bool add = u;
@ -53,7 +53,7 @@ bool ArmTranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Re
} }
// MCR{2}<c> <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2> // MCR{2}<c> <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2>
bool ArmTranslatorVisitor::arm_MCR(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) { bool TranslatorVisitor::arm_MCR(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) {
if ((coproc_no & 0b1110) == 0b1010) { if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
} }
@ -64,14 +64,14 @@ bool ArmTranslatorVisitor::arm_MCR(Cond cond, size_t opc1, CoprocReg CRn, Reg t,
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t)); ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t));
} }
return true; return true;
} }
// MCRR{2}<c> <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm> // MCRR{2}<c> <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm>
bool ArmTranslatorVisitor::arm_MCRR(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) { bool TranslatorVisitor::arm_MCRR(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) {
if ((coproc_no & 0b1110) == 0b1010) { if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
} }
@ -82,21 +82,21 @@ bool ArmTranslatorVisitor::arm_MCRR(Cond cond, Reg t2, Reg t, size_t coproc_no,
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2)); ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2));
} }
return true; return true;
} }
// MRC{2}<c> <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2> // MRC{2}<c> <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2>
bool ArmTranslatorVisitor::arm_MRC(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) { bool TranslatorVisitor::arm_MRC(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) {
if ((coproc_no & 0b1110) == 0b1010) { if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
} }
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
const auto word = ir.CoprocGetOneWord(coproc_no, two, opc1, CRn, CRm, opc2); const auto word = ir.CoprocGetOneWord(coproc_no, two, opc1, CRn, CRm, opc2);
if (t != Reg::PC) { if (t != Reg::PC) {
ir.SetRegister(t, word); ir.SetRegister(t, word);
@ -109,7 +109,7 @@ bool ArmTranslatorVisitor::arm_MRC(Cond cond, size_t opc1, CoprocReg CRn, Reg t,
} }
// MRRC{2}<c> <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm> // MRRC{2}<c> <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm>
bool ArmTranslatorVisitor::arm_MRRC(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) { bool TranslatorVisitor::arm_MRRC(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) {
if ((coproc_no & 0b1110) == 0b1010) { if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
} }
@ -120,7 +120,7 @@ bool ArmTranslatorVisitor::arm_MRRC(Cond cond, Reg t2, Reg t, size_t coproc_no,
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
const auto two_words = ir.CoprocGetTwoWords(coproc_no, two, opc, CRm); const auto two_words = ir.CoprocGetTwoWords(coproc_no, two, opc, CRm);
ir.SetRegister(t, ir.LeastSignificantWord(two_words)); ir.SetRegister(t, ir.LeastSignificantWord(two_words));
ir.SetRegister(t2, ir.MostSignificantWord(two_words).result); ir.SetRegister(t2, ir.MostSignificantWord(two_words).result);
@ -131,7 +131,7 @@ bool ArmTranslatorVisitor::arm_MRRC(Cond cond, Reg t2, Reg t, size_t coproc_no,
// STC{2}{L}<c> <coproc>, <CRd>, [<Rn>, #+/-<imm32>]{!} // STC{2}{L}<c> <coproc>, <CRd>, [<Rn>, #+/-<imm32>]{!}
// STC{2}{L}<c> <coproc>, <CRd>, [<Rn>], #+/-<imm32> // STC{2}{L}<c> <coproc>, <CRd>, [<Rn>], #+/-<imm32>
// STC{2}{L}<c> <coproc>, <CRd>, [<Rn>], <imm8> // STC{2}{L}<c> <coproc>, <CRd>, [<Rn>], <imm8>
bool ArmTranslatorVisitor::arm_STC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8) { bool TranslatorVisitor::arm_STC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8) {
if ((coproc_no & 0b1110) == 0b1010) { if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
} }
@ -146,7 +146,7 @@ bool ArmTranslatorVisitor::arm_STC(Cond cond, bool p, bool u, bool d, bool w, Re
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) { if (two || ArmConditionPassed(cond)) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const bool index = p; const bool index = p;
const bool add = u; const bool add = u;

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
@ -37,7 +37,7 @@ enum class CRCType {
ISO, ISO,
}; };
bool CRC32Variant(ArmTranslatorVisitor& v, Cond cond, Imm<2> sz, Reg n, Reg d, Reg m, CRCType type) { bool CRC32Variant(TranslatorVisitor& v, Cond cond, Imm<2> sz, Reg n, Reg d, Reg m, CRCType type) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -83,12 +83,12 @@ bool CRC32Variant(ArmTranslatorVisitor& v, Cond cond, Imm<2> sz, Reg n, Reg d, R
} // Anonymous namespace } // Anonymous namespace
// CRC32{B,H,W}{<q>} <Rd>, <Rn>, <Rm> // CRC32{B,H,W}{<q>} <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_CRC32(Cond cond, Imm<2> sz, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_CRC32(Cond cond, Imm<2> sz, Reg n, Reg d, Reg m) {
return CRC32Variant(*this, cond, sz, n, d, m, CRCType::ISO); return CRC32Variant(*this, cond, sz, n, d, m, CRCType::ISO);
} }
// CRC32C{B,H,W}{<q>} <Rd>, <Rn>, <Rm> // CRC32C{B,H,W}{<q>} <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_CRC32C(Cond cond, Imm<2> sz, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_CRC32C(Cond cond, Imm<2> sz, Reg n, Reg d, Reg m) {
return CRC32Variant(*this, cond, sz, n, d, m, CRCType::Castagnoli); return CRC32Variant(*this, cond, sz, n, d, m, CRCType::Castagnoli);
} }

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// ADC{S}<c> <Rd>, <Rn>, #<imm> // ADC{S}<c> <Rd>, <Rn>, #<imm>
bool ArmTranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -37,8 +37,8 @@ bool ArmTranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// ADC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // ADC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -67,12 +67,12 @@ bool ArmTranslatorVisitor::arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// ADC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // ADC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_ADC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_ADC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -93,8 +93,8 @@ bool ArmTranslatorVisitor::arm_ADC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// ADD{S}<c> <Rd>, <Rn>, #<const> // ADD{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -123,8 +123,8 @@ bool ArmTranslatorVisitor::arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// ADD{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // ADD{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -153,12 +153,12 @@ bool ArmTranslatorVisitor::arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// ADD{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // ADD{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_ADD_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_ADD_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -179,8 +179,8 @@ bool ArmTranslatorVisitor::arm_ADD_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// AND{S}<c> <Rd>, <Rn>, #<const> // AND{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -208,8 +208,8 @@ bool ArmTranslatorVisitor::arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// AND{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // AND{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -237,12 +237,12 @@ bool ArmTranslatorVisitor::arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// AND{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // AND{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_AND_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_AND_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -262,8 +262,8 @@ bool ArmTranslatorVisitor::arm_AND_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// BIC{S}<c> <Rd>, <Rn>, #<const> // BIC{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -291,8 +291,8 @@ bool ArmTranslatorVisitor::arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// BIC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // BIC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -321,12 +321,12 @@ bool ArmTranslatorVisitor::arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// BIC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // BIC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_BIC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_BIC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -346,8 +346,8 @@ bool ArmTranslatorVisitor::arm_BIC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// CMN<c> <Rn>, #<const> // CMN<c> <Rn>, #<const>
bool ArmTranslatorVisitor::arm_CMN_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_CMN_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -362,8 +362,8 @@ bool ArmTranslatorVisitor::arm_CMN_imm(Cond cond, Reg n, int rotate, Imm<8> imm8
} }
// CMN<c> <Rn>, <Rm>{, <shift>} // CMN<c> <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_CMN_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_CMN_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -378,12 +378,12 @@ bool ArmTranslatorVisitor::arm_CMN_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType
} }
// CMN<c> <Rn>, <Rm>, <type> <Rs> // CMN<c> <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -400,8 +400,8 @@ bool ArmTranslatorVisitor::arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift,
} }
// CMP<c> <Rn>, #<imm> // CMP<c> <Rn>, #<imm>
bool ArmTranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -416,8 +416,8 @@ bool ArmTranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm<8> imm8
} }
// CMP<c> <Rn>, <Rm>{, <shift>} // CMP<c> <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -432,12 +432,12 @@ bool ArmTranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType
} }
// CMP<c> <Rn>, <Rm>, <type> <Rs> // CMP<c> <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -454,8 +454,8 @@ bool ArmTranslatorVisitor::arm_CMP_rsr(Cond cond, Reg n, Reg s, ShiftType shift,
} }
// EOR{S}<c> <Rd>, <Rn>, #<const> // EOR{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -483,8 +483,8 @@ bool ArmTranslatorVisitor::arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// EOR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // EOR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -513,12 +513,12 @@ bool ArmTranslatorVisitor::arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// EOR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // EOR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_EOR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_EOR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -538,8 +538,8 @@ bool ArmTranslatorVisitor::arm_EOR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// MOV{S}<c> <Rd>, #<const> // MOV{S}<c> <Rd>, #<const>
bool ArmTranslatorVisitor::arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -567,8 +567,8 @@ bool ArmTranslatorVisitor::arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm
} }
// MOV{S}<c> <Rd>, <Rm> // MOV{S}<c> <Rd>, <Rm>
bool ArmTranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -596,12 +596,12 @@ bool ArmTranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm<5> imm5, Sh
return true; return true;
} }
bool ArmTranslatorVisitor::arm_MOV_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_MOV_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -620,8 +620,8 @@ bool ArmTranslatorVisitor::arm_MOV_rsr(Cond cond, bool S, Reg d, Reg s, ShiftTyp
} }
// MVN{S}<c> <Rd>, #<const> // MVN{S}<c> <Rd>, #<const>
bool ArmTranslatorVisitor::arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -649,8 +649,8 @@ bool ArmTranslatorVisitor::arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm
} }
// MVN{S}<c> <Rd>, <Rm>{, <shift>} // MVN{S}<c> <Rd>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_MVN_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_MVN_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -679,12 +679,12 @@ bool ArmTranslatorVisitor::arm_MVN_reg(Cond cond, bool S, Reg d, Imm<5> imm5, Sh
} }
// MVN{S}<c> <Rd>, <Rm>, <type> <Rs> // MVN{S}<c> <Rd>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_MVN_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_MVN_rsr(Cond cond, bool S, Reg d, Reg s, ShiftType shift, Reg m) {
if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -704,8 +704,8 @@ bool ArmTranslatorVisitor::arm_MVN_rsr(Cond cond, bool S, Reg d, Reg s, ShiftTyp
} }
// ORR{S}<c> <Rd>, <Rn>, #<const> // ORR{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -733,8 +733,8 @@ bool ArmTranslatorVisitor::arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// ORR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // ORR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -763,12 +763,12 @@ bool ArmTranslatorVisitor::arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// ORR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // ORR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_ORR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_ORR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -788,8 +788,8 @@ bool ArmTranslatorVisitor::arm_ORR_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// RSB{S}<c> <Rd>, <Rn>, #<const> // RSB{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -818,8 +818,8 @@ bool ArmTranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// RSB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // RSB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -848,12 +848,12 @@ bool ArmTranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// RSB{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // RSB{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -874,8 +874,8 @@ bool ArmTranslatorVisitor::arm_RSB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// RSC{S}<c> <Rd>, <Rn>, #<const> // RSC{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -903,8 +903,8 @@ bool ArmTranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rota
return true; return true;
} }
bool ArmTranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -933,12 +933,12 @@ bool ArmTranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// RSC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // RSC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -959,8 +959,8 @@ bool ArmTranslatorVisitor::arm_RSC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// SBC{S}<c> <Rd>, <Rn>, #<const> // SBC{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -989,8 +989,8 @@ bool ArmTranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// SBC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // SBC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1019,12 +1019,12 @@ bool ArmTranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
} }
// SBC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> // SBC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1045,8 +1045,8 @@ bool ArmTranslatorVisitor::arm_SBC_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// SUB{S}<c> <Rd>, <Rn>, #<const> // SUB{S}<c> <Rd>, <Rn>, #<const>
bool ArmTranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1075,8 +1075,8 @@ bool ArmTranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rota
} }
// SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>} // SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1104,12 +1104,12 @@ bool ArmTranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
return true; return true;
} }
bool ArmTranslatorVisitor::arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC || d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1130,8 +1130,8 @@ bool ArmTranslatorVisitor::arm_SUB_rsr(Cond cond, bool S, Reg n, Reg d, Reg s, S
} }
// TEQ<c> <Rn>, #<const> // TEQ<c> <Rn>, #<const>
bool ArmTranslatorVisitor::arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1145,8 +1145,8 @@ bool ArmTranslatorVisitor::arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm<8> imm8
} }
// TEQ<c> <Rn>, <Rm>{, <shift>} // TEQ<c> <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_TEQ_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_TEQ_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1161,12 +1161,12 @@ bool ArmTranslatorVisitor::arm_TEQ_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType
} }
// TEQ<c> <Rn>, <Rm>, <type> <Rs> // TEQ<c> <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1182,8 +1182,8 @@ bool ArmTranslatorVisitor::arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift,
} }
// TST<c> <Rn>, #<const> // TST<c> <Rn>, #<const>
bool ArmTranslatorVisitor::arm_TST_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_TST_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1197,8 +1197,8 @@ bool ArmTranslatorVisitor::arm_TST_imm(Cond cond, Reg n, int rotate, Imm<8> imm8
} }
// TST<c> <Rn>, <Rm>{, <shift>} // TST<c> <Rn>, <Rm>{, <shift>}
bool ArmTranslatorVisitor::arm_TST_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_TST_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -1213,12 +1213,12 @@ bool ArmTranslatorVisitor::arm_TST_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType
} }
// TST<c> <Rn>, <Rm>, <type> <Rs> // TST<c> <Rn>, <Rm>, <type> <Rs>
bool ArmTranslatorVisitor::arm_TST_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_TST_rsr(Cond cond, Reg n, Reg s, ShiftType shift, Reg m) {
if (n == Reg::PC || m == Reg::PC || s == Reg::PC) { if (n == Reg::PC || m == Reg::PC || s == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,19 +3,19 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
using DivideFunction = IR::U32U64 (IREmitter::*)(const IR::U32U64&, const IR::U32U64&); using DivideFunction = IR::U32U64 (IREmitter::*)(const IR::U32U64&, const IR::U32U64&);
bool DivideOperation(ArmTranslatorVisitor& v, Cond cond, Reg d, Reg m, Reg n, bool DivideOperation(TranslatorVisitor& v, Cond cond, Reg d, Reg m, Reg n,
DivideFunction fn) { DivideFunction fn) {
if (d == Reg::PC || m == Reg::PC || n == Reg::PC) { if (d == Reg::PC || m == Reg::PC || n == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
if (!v.ConditionPassed(cond)) { if (!v.ArmConditionPassed(cond)) {
return true; return true;
} }
@ -29,12 +29,12 @@ bool DivideOperation(ArmTranslatorVisitor& v, Cond cond, Reg d, Reg m, Reg n,
} // Anonymous namespace } // Anonymous namespace
// SDIV<c> <Rd>, <Rn>, <Rm> // SDIV<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SDIV(Cond cond, Reg d, Reg m, Reg n) { bool TranslatorVisitor::arm_SDIV(Cond cond, Reg d, Reg m, Reg n) {
return DivideOperation(*this, cond, d, m, n, &IREmitter::SignedDiv); return DivideOperation(*this, cond, d, m, n, &IREmitter::SignedDiv);
} }
// UDIV<c> <Rd>, <Rn>, <Rm> // UDIV<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UDIV(Cond cond, Reg d, Reg m, Reg n) { bool TranslatorVisitor::arm_UDIV(Cond cond, Reg d, Reg m, Reg n) {
return DivideOperation(*this, cond, d, m, n, &IREmitter::UnsignedDiv); return DivideOperation(*this, cond, d, m, n, &IREmitter::UnsignedDiv);
} }

View file

@ -3,20 +3,20 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include <dynarmic/A32/config.h> #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/impl/translate_arm.h" #include <dynarmic/A32/config.h>
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// BKPT #<imm16> // BKPT #<imm16>
bool ArmTranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*/) { bool TranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*/) {
if (cond != Cond::AL && !options.define_unpredictable_behaviour) { if (cond != Cond::AL && !options.define_unpredictable_behaviour) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
// UNPREDICTABLE: The instruction executes conditionally. // UNPREDICTABLE: The instruction executes conditionally.
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -26,8 +26,8 @@ bool ArmTranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*
} }
// SVC<c> #<imm24> // SVC<c> #<imm24>
bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm<24> imm24) { bool TranslatorVisitor::arm_SVC(Cond cond, Imm<24> imm24) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -40,7 +40,7 @@ bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm<24> imm24) {
} }
// UDF<c> #<imm16> // UDF<c> #<imm16>
bool ArmTranslatorVisitor::arm_UDF() { bool TranslatorVisitor::arm_UDF() {
return UndefinedInstruction(); return UndefinedInstruction();
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
@ -13,12 +13,12 @@ static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
} }
// SXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>} // SXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_SXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_SXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -31,12 +31,12 @@ bool ArmTranslatorVisitor::arm_SXTAB(Cond cond, Reg n, Reg d, SignExtendRotation
} }
// SXTAB16<c> <Rd>, <Rn>, <Rm>{, <rotation>} // SXTAB16<c> <Rd>, <Rn>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_SXTAB16(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_SXTAB16(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -51,12 +51,12 @@ bool ArmTranslatorVisitor::arm_SXTAB16(Cond cond, Reg n, Reg d, SignExtendRotati
} }
// SXTAH<c> <Rd>, <Rn>, <Rm>{, <rotation>} // SXTAH<c> <Rd>, <Rn>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_SXTAH(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_SXTAH(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -69,12 +69,12 @@ bool ArmTranslatorVisitor::arm_SXTAH(Cond cond, Reg n, Reg d, SignExtendRotation
} }
// SXTB<c> <Rd>, <Rm>{, <rotation>} // SXTB<c> <Rd>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_SXTB(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_SXTB(Cond cond, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -86,12 +86,12 @@ bool ArmTranslatorVisitor::arm_SXTB(Cond cond, Reg d, SignExtendRotation rotate,
} }
// SXTB16<c> <Rd>, <Rm>{, <rotation>} // SXTB16<c> <Rd>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_SXTB16(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_SXTB16(Cond cond, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -105,12 +105,12 @@ bool ArmTranslatorVisitor::arm_SXTB16(Cond cond, Reg d, SignExtendRotation rotat
} }
// SXTH<c> <Rd>, <Rm>{, <rotation>} // SXTH<c> <Rd>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_SXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_SXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -122,12 +122,12 @@ bool ArmTranslatorVisitor::arm_SXTH(Cond cond, Reg d, SignExtendRotation rotate,
} }
// UXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>} // UXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_UXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_UXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -140,12 +140,12 @@ bool ArmTranslatorVisitor::arm_UXTAB(Cond cond, Reg n, Reg d, SignExtendRotation
} }
// UXTAB16<c> <Rd>, <Rn>, <Rm>{, <rotation>} // UXTAB16<c> <Rd>, <Rn>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_UXTAB16(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_UXTAB16(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC || n == Reg::PC) { if (d == Reg::PC || m == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -159,12 +159,12 @@ bool ArmTranslatorVisitor::arm_UXTAB16(Cond cond, Reg n, Reg d, SignExtendRotati
} }
// UXTAH<c> <Rd>, <Rn>, <Rm>{, <rotation>} // UXTAH<c> <Rd>, <Rn>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_UXTAH(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_UXTAH(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -177,12 +177,12 @@ bool ArmTranslatorVisitor::arm_UXTAH(Cond cond, Reg n, Reg d, SignExtendRotation
} }
// UXTB<c> <Rd>, <Rm>{, <rotation>} // UXTB<c> <Rd>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_UXTB(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_UXTB(Cond cond, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -193,12 +193,12 @@ bool ArmTranslatorVisitor::arm_UXTB(Cond cond, Reg d, SignExtendRotation rotate,
} }
// UXTB16<c> <Rd>, <Rm>{, <rotation>} // UXTB16<c> <Rd>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_UXTB16(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_UXTB16(Cond cond, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -210,12 +210,12 @@ bool ArmTranslatorVisitor::arm_UXTB16(Cond cond, Reg d, SignExtendRotation rotat
} }
// UXTH<c> <Rd>, <Rm>{, <rotation>} // UXTH<c> <Rd>, <Rm>{, <rotation>}
bool ArmTranslatorVisitor::arm_UXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::arm_UXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,40 +3,31 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include <dynarmic/A32/config.h> #include <dynarmic/A32/config.h>
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ArmTranslatorVisitor::arm_PLD_imm([[maybe_unused]] bool add, bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*imm12*/) {
bool R,
[[maybe_unused]] Reg n,
[[maybe_unused]] Imm<12> imm12) {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
const auto exception = R ? Exception::PreloadData const auto exception = R ? Exception::PreloadData : Exception::PreloadDataWithIntentToWrite;
: Exception::PreloadDataWithIntentToWrite;
return RaiseException(exception); return RaiseException(exception);
} }
bool ArmTranslatorVisitor::arm_PLD_reg([[maybe_unused]] bool add, bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*imm5*/, ShiftType /*shift*/, Reg /*m*/) {
bool R,
[[maybe_unused]] Reg n,
[[maybe_unused]] Imm<5> imm5,
[[maybe_unused]] ShiftType shift,
[[maybe_unused]] Reg m) {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
const auto exception = R ? Exception::PreloadData const auto exception = R ? Exception::PreloadData : Exception::PreloadDataWithIntentToWrite;
: Exception::PreloadDataWithIntentToWrite;
return RaiseException(exception); return RaiseException(exception);
} }
bool ArmTranslatorVisitor::arm_SEV() { bool TranslatorVisitor::arm_SEV() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -44,7 +35,7 @@ bool ArmTranslatorVisitor::arm_SEV() {
return RaiseException(Exception::SendEvent); return RaiseException(Exception::SendEvent);
} }
bool ArmTranslatorVisitor::arm_SEVL() { bool TranslatorVisitor::arm_SEVL() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -52,7 +43,7 @@ bool ArmTranslatorVisitor::arm_SEVL() {
return RaiseException(Exception::SendEventLocal); return RaiseException(Exception::SendEventLocal);
} }
bool ArmTranslatorVisitor::arm_WFE() { bool TranslatorVisitor::arm_WFE() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -60,7 +51,7 @@ bool ArmTranslatorVisitor::arm_WFE() {
return RaiseException(Exception::WaitForEvent); return RaiseException(Exception::WaitForEvent);
} }
bool ArmTranslatorVisitor::arm_WFI() { bool TranslatorVisitor::arm_WFI() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -68,7 +59,7 @@ bool ArmTranslatorVisitor::arm_WFI() {
return RaiseException(Exception::WaitForInterrupt); return RaiseException(Exception::WaitForInterrupt);
} }
bool ArmTranslatorVisitor::arm_YIELD() { bool TranslatorVisitor::arm_YIELD() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }

View file

@ -3,46 +3,46 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ArmTranslatorVisitor::arm_LDRBT() { bool TranslatorVisitor::arm_LDRBT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_LDRHT() { bool TranslatorVisitor::arm_LDRHT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_LDRSBT() { bool TranslatorVisitor::arm_LDRSBT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_LDRSHT() { bool TranslatorVisitor::arm_LDRSHT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_LDRT() { bool TranslatorVisitor::arm_LDRT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_STRBT() { bool TranslatorVisitor::arm_STRBT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_STRHT() { bool TranslatorVisitor::arm_STRHT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
bool ArmTranslatorVisitor::arm_STRT() { bool TranslatorVisitor::arm_STRT() {
// System instructions unimplemented // System instructions unimplemented
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -63,8 +63,8 @@ static IR::U32 GetAddress(A32::IREmitter& ir, bool P, bool U, bool W, Reg n, IR:
} }
// LDR <Rt>, [PC, #+/-<imm>] // LDR <Rt>, [PC, #+/-<imm>]
bool ArmTranslatorVisitor::arm_LDR_lit(Cond cond, bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::arm_LDR_lit(Cond cond, bool U, Reg t, Imm<12> imm12) {
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -85,7 +85,7 @@ bool ArmTranslatorVisitor::arm_LDR_lit(Cond cond, bool U, Reg t, Imm<12> imm12)
// LDR <Rt>, [<Rn>, #+/-<imm>]{!} // LDR <Rt>, [<Rn>, #+/-<imm>]{!}
// LDR <Rt>, [<Rn>], #+/-<imm> // LDR <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -95,7 +95,7 @@ bool ArmTranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -122,7 +122,7 @@ bool ArmTranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n,
// LDR <Rt>, [<Rn>, #+/-<Rm>]{!} // LDR <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDR <Rt>, [<Rn>], #+/-<Rm> // LDR <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented"); ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -132,7 +132,7 @@ bool ArmTranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -151,12 +151,12 @@ bool ArmTranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n,
} }
// LDRB <Rt>, [PC, #+/-<imm>] // LDRB <Rt>, [PC, #+/-<imm>]
bool ArmTranslatorVisitor::arm_LDRB_lit(Cond cond, bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::arm_LDRB_lit(Cond cond, bool U, Reg t, Imm<12> imm12) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -172,7 +172,7 @@ bool ArmTranslatorVisitor::arm_LDRB_lit(Cond cond, bool U, Reg t, Imm<12> imm12)
// LDRB <Rt>, [<Rn>, #+/-<imm>]{!} // LDRB <Rt>, [<Rn>, #+/-<imm>]{!}
// LDRB <Rt>, [<Rn>], #+/-<imm> // LDRB <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -186,7 +186,7 @@ bool ArmTranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -201,7 +201,7 @@ bool ArmTranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n
// LDRB <Rt>, [<Rn>, #+/-<Rm>]{!} // LDRB <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRB <Rt>, [<Rn>], #+/-<Rm> // LDRB <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented"); ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) { if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -211,7 +211,7 @@ bool ArmTranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -224,7 +224,7 @@ bool ArmTranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n
} }
// LDRD <Rt>, <Rt2>, [PC, #+/-<imm>] // LDRD <Rt>, <Rt2>, [PC, #+/-<imm>]
bool ArmTranslatorVisitor::arm_LDRD_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRD_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (RegNumber(t) % 2 == 1) { if (RegNumber(t) % 2 == 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -233,7 +233,7 @@ bool ArmTranslatorVisitor::arm_LDRD_lit(Cond cond, bool U, Reg t, Imm<4> imm8a,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -253,7 +253,7 @@ bool ArmTranslatorVisitor::arm_LDRD_lit(Cond cond, bool U, Reg t, Imm<4> imm8a,
// LDRD <Rt>, [<Rn>, #+/-<imm>]{!} // LDRD <Rt>, [<Rn>, #+/-<imm>]{!}
// LDRD <Rt>, [<Rn>], #+/-<imm> // LDRD <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -274,7 +274,7 @@ bool ArmTranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -294,7 +294,7 @@ bool ArmTranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n
// LDRD <Rt>, [<Rn>, #+/-<Rm>]{!} // LDRD <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRD <Rt>, [<Rn>], #+/-<Rm> // LDRD <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) { bool TranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
if (RegNumber(t) % 2 == 1) { if (RegNumber(t) % 2 == 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -311,7 +311,7 @@ bool ArmTranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -328,7 +328,7 @@ bool ArmTranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n
} }
// LDRH <Rt>, [PC, #-/+<imm>] // LDRH <Rt>, [PC, #-/+<imm>]
bool ArmTranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented"); ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
if (P == W) { if (P == W) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -338,7 +338,7 @@ bool ArmTranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -354,7 +354,7 @@ bool ArmTranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t
// LDRH <Rt>, [<Rn>, #+/-<imm>]{!} // LDRH <Rt>, [<Rn>, #+/-<imm>]{!}
// LDRH <Rt>, [<Rn>], #+/-<imm> // LDRH <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -368,7 +368,7 @@ bool ArmTranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -383,7 +383,7 @@ bool ArmTranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n
// LDRH <Rt>, [<Rn>, #+/-<Rm>]{!} // LDRH <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRH <Rt>, [<Rn>], #+/-<Rm> // LDRH <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) { bool TranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented"); ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) { if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -393,7 +393,7 @@ bool ArmTranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -406,12 +406,12 @@ bool ArmTranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n
} }
// LDRSB <Rt>, [PC, #+/-<imm>] // LDRSB <Rt>, [PC, #+/-<imm>]
bool ArmTranslatorVisitor::arm_LDRSB_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRSB_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -428,7 +428,7 @@ bool ArmTranslatorVisitor::arm_LDRSB_lit(Cond cond, bool U, Reg t, Imm<4> imm8a,
// LDRSB <Rt>, [<Rn>, #+/-<imm>]{!} // LDRSB <Rt>, [<Rn>, #+/-<imm>]{!}
// LDRSB <Rt>, [<Rn>], #+/-<imm> // LDRSB <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -442,7 +442,7 @@ bool ArmTranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -457,7 +457,7 @@ bool ArmTranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg
// LDRSB <Rt>, [<Rn>, #+/-<Rm>]{!} // LDRSB <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRSB <Rt>, [<Rn>], #+/-<Rm> // LDRSB <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) { bool TranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented"); ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) { if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -467,7 +467,7 @@ bool ArmTranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -480,12 +480,12 @@ bool ArmTranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg
} }
// LDRSH <Rt>, [PC, #-/+<imm>] // LDRSH <Rt>, [PC, #-/+<imm>]
bool ArmTranslatorVisitor::arm_LDRSH_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRSH_lit(Cond cond, bool U, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -501,7 +501,7 @@ bool ArmTranslatorVisitor::arm_LDRSH_lit(Cond cond, bool U, Reg t, Imm<4> imm8a,
// LDRSH <Rt>, [<Rn>, #+/-<imm>]{!} // LDRSH <Rt>, [<Rn>, #+/-<imm>]{!}
// LDRSH <Rt>, [<Rn>], #+/-<imm> // LDRSH <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -515,7 +515,7 @@ bool ArmTranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -530,7 +530,7 @@ bool ArmTranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg
// LDRSH <Rt>, [<Rn>, #+/-<Rm>]{!} // LDRSH <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRSH <Rt>, [<Rn>], #+/-<Rm> // LDRSH <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) { bool TranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented"); ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) { if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -540,7 +540,7 @@ bool ArmTranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -554,12 +554,12 @@ bool ArmTranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg
// STR <Rt>, [<Rn>, #+/-<imm>]{!} // STR <Rt>, [<Rn>, #+/-<imm>]{!}
// STR <Rt>, [<Rn>], #+/-<imm> // STR <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) {
if ((!P || W) && (n == Reg::PC || n == t)) { if ((!P || W) && (n == Reg::PC || n == t)) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -571,7 +571,7 @@ bool ArmTranslatorVisitor::arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n,
// STR <Rt>, [<Rn>, #+/-<Rm>]{!} // STR <Rt>, [<Rn>, #+/-<Rm>]{!}
// STR <Rt>, [<Rn>], #+/-<Rm> // STR <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -580,7 +580,7 @@ bool ArmTranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -592,7 +592,7 @@ bool ArmTranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n,
// STRB <Rt>, [<Rn>, #+/-<imm>]{!} // STRB <Rt>, [<Rn>, #+/-<imm>]{!}
// STRB <Rt>, [<Rn>], #+/-<imm> // STRB <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<12> imm12) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -601,7 +601,7 @@ bool ArmTranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -613,7 +613,7 @@ bool ArmTranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n
// STRB <Rt>, [<Rn>, #+/-<Rm>]{!} // STRB <Rt>, [<Rn>, #+/-<Rm>]{!}
// STRB <Rt>, [<Rn>], #+/-<Rm> // STRB <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) { bool TranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
if (t == Reg::PC || m == Reg::PC) { if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -622,7 +622,7 @@ bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -634,7 +634,7 @@ bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n
// STRD <Rt>, [<Rn>, #+/-<imm>]{!} // STRD <Rt>, [<Rn>, #+/-<imm>]{!}
// STRD <Rt>, [<Rn>], #+/-<imm> // STRD <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (size_t(t) % 2 != 0) { if (size_t(t) % 2 != 0) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -652,7 +652,7 @@ bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -670,7 +670,7 @@ bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n
// STRD <Rt>, [<Rn>, #+/-<Rm>]{!} // STRD <Rt>, [<Rn>, #+/-<Rm>]{!}
// STRD <Rt>, [<Rn>], #+/-<Rm> // STRD <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) { bool TranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
if (size_t(t) % 2 != 0) { if (size_t(t) % 2 != 0) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -688,7 +688,7 @@ bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -705,7 +705,7 @@ bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n
// STRH <Rt>, [<Rn>, #+/-<imm>]{!} // STRH <Rt>, [<Rn>, #+/-<imm>]{!}
// STRH <Rt>, [<Rn>], #+/-<imm> // STRH <Rt>, [<Rn>], #+/-<imm>
bool ArmTranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) { bool TranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -714,7 +714,7 @@ bool ArmTranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -728,7 +728,7 @@ bool ArmTranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n
// STRH <Rt>, [<Rn>, #+/-<Rm>]{!} // STRH <Rt>, [<Rn>, #+/-<Rm>]{!}
// STRH <Rt>, [<Rn>], #+/-<Rm> // STRH <Rt>, [<Rn>], #+/-<Rm>
bool ArmTranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) { bool TranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
if (t == Reg::PC || m == Reg::PC) { if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -737,7 +737,7 @@ bool ArmTranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -771,7 +771,7 @@ static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
} }
// LDM <Rn>{!}, <reg_list> // LDM <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -779,7 +779,7 @@ bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -789,7 +789,7 @@ bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
} }
// LDMDA <Rn>{!}, <reg_list> // LDMDA <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -797,7 +797,7 @@ bool ArmTranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -807,7 +807,7 @@ bool ArmTranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) {
} }
// LDMDB <Rn>{!}, <reg_list> // LDMDB <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -815,7 +815,7 @@ bool ArmTranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -825,7 +825,7 @@ bool ArmTranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) {
} }
// LDMIB <Rn>{!}, <reg_list> // LDMIB <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -833,7 +833,7 @@ bool ArmTranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -842,11 +842,11 @@ bool ArmTranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) {
return LDMHelper(ir, W, n, list, start_address, writeback_address); return LDMHelper(ir, W, n, list, start_address, writeback_address);
} }
bool ArmTranslatorVisitor::arm_LDM_usr() { bool TranslatorVisitor::arm_LDM_usr() {
return InterpretThisInstruction(); return InterpretThisInstruction();
} }
bool ArmTranslatorVisitor::arm_LDM_eret() { bool TranslatorVisitor::arm_LDM_eret() {
return InterpretThisInstruction(); return InterpretThisInstruction();
} }
@ -868,12 +868,12 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, RegList list, IR::U32 s
} }
// STM <Rn>{!}, <reg_list> // STM <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -883,12 +883,12 @@ bool ArmTranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList list) {
} }
// STMDA <Rn>{!}, <reg_list> // STMDA <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -898,12 +898,12 @@ bool ArmTranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList list) {
} }
// STMDB <Rn>{!}, <reg_list> // STMDB <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -913,12 +913,12 @@ bool ArmTranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList list) {
} }
// STMIB <Rn>{!}, <reg_list> // STMIB <Rn>{!}, <reg_list>
bool ArmTranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) { bool TranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) {
if (n == Reg::PC || Common::BitCount(list) < 1) { if (n == Reg::PC || Common::BitCount(list) < 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -927,7 +927,7 @@ bool ArmTranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) {
return STMHelper(ir, W, n, list, start_address, writeback_address); return STMHelper(ir, W, n, list, start_address, writeback_address);
} }
bool ArmTranslatorVisitor::arm_STM_usr() { bool TranslatorVisitor::arm_STM_usr() {
return InterpretThisInstruction(); return InterpretThisInstruction();
} }

View file

@ -3,13 +3,14 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// BFC<c> <Rd>, #<lsb>, #<width> // BFC<c> <Rd>, #<lsb>, #<width>
bool ArmTranslatorVisitor::arm_BFC(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb) { bool TranslatorVisitor::arm_BFC(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -17,7 +18,7 @@ bool ArmTranslatorVisitor::arm_BFC(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -32,7 +33,7 @@ bool ArmTranslatorVisitor::arm_BFC(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb) {
} }
// BFI<c> <Rd>, <Rn>, #<lsb>, #<width> // BFI<c> <Rd>, <Rn>, #<lsb>, #<width>
bool ArmTranslatorVisitor::arm_BFI(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb, Reg n) { bool TranslatorVisitor::arm_BFI(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb, Reg n) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -40,7 +41,7 @@ bool ArmTranslatorVisitor::arm_BFI(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -57,12 +58,12 @@ bool ArmTranslatorVisitor::arm_BFI(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb, Reg
} }
// CLZ<c> <Rd>, <Rm> // CLZ<c> <Rd>, <Rm>
bool ArmTranslatorVisitor::arm_CLZ(Cond cond, Reg d, Reg m) { bool TranslatorVisitor::arm_CLZ(Cond cond, Reg d, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -71,12 +72,12 @@ bool ArmTranslatorVisitor::arm_CLZ(Cond cond, Reg d, Reg m) {
} }
// MOVT<c> <Rd>, #<imm16> // MOVT<c> <Rd>, #<imm16>
bool ArmTranslatorVisitor::arm_MOVT(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12) { bool TranslatorVisitor::arm_MOVT(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -88,12 +89,12 @@ bool ArmTranslatorVisitor::arm_MOVT(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12
return true; return true;
} }
bool ArmTranslatorVisitor::arm_MOVW(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12) { bool TranslatorVisitor::arm_MOVW(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -104,7 +105,7 @@ bool ArmTranslatorVisitor::arm_MOVW(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12
} }
// SBFX<c> <Rd>, <Rn>, #<lsb>, #<width> // SBFX<c> <Rd>, <Rn>, #<lsb>, #<width>
bool ArmTranslatorVisitor::arm_SBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb, Reg n) { bool TranslatorVisitor::arm_SBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb, Reg n) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -116,7 +117,7 @@ bool ArmTranslatorVisitor::arm_SBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -133,12 +134,12 @@ bool ArmTranslatorVisitor::arm_SBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb
} }
// SEL<c> <Rd>, <Rn>, <Rm> // SEL<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) {
if (n == Reg::PC || d == Reg::PC || m == Reg::PC) { if (n == Reg::PC || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -151,7 +152,7 @@ bool ArmTranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) {
} }
// UBFX<c> <Rd>, <Rn>, #<lsb>, #<width> // UBFX<c> <Rd>, <Rn>, #<lsb>, #<width>
bool ArmTranslatorVisitor::arm_UBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb, Reg n) { bool TranslatorVisitor::arm_UBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb, Reg n) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -163,7 +164,7 @@ bool ArmTranslatorVisitor::arm_UBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// MLA{S}<c> <Rd>, <Rn>, <Rm>, <Ra> // MLA{S}<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n) { bool TranslatorVisitor::arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -28,12 +28,12 @@ bool ArmTranslatorVisitor::arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n
} }
// MLS<c> <Rd>, <Rn>, <Rm>, <Ra> // MLS<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_MLS(Cond cond, Reg d, Reg a, Reg m, Reg n) { bool TranslatorVisitor::arm_MLS(Cond cond, Reg d, Reg a, Reg m, Reg n) {
if (d == Reg::PC || a == Reg::PC || m == Reg::PC || n == Reg::PC) { if (d == Reg::PC || a == Reg::PC || m == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -47,12 +47,12 @@ bool ArmTranslatorVisitor::arm_MLS(Cond cond, Reg d, Reg a, Reg m, Reg n) {
} }
// MUL{S}<c> <Rd>, <Rn>, <Rm> // MUL{S}<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) { bool TranslatorVisitor::arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -68,7 +68,7 @@ bool ArmTranslatorVisitor::arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) {
// SMLAL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm> // SMLAL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) { bool TranslatorVisitor::arm_SMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -77,7 +77,7 @@ bool ArmTranslatorVisitor::arm_SMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -100,7 +100,7 @@ bool ArmTranslatorVisitor::arm_SMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
} }
// SMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm> // SMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) { bool TranslatorVisitor::arm_SMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -109,7 +109,7 @@ bool ArmTranslatorVisitor::arm_SMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -130,7 +130,7 @@ bool ArmTranslatorVisitor::arm_SMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
} }
// UMAAL<c> <RdLo>, <RdHi>, <Rn>, <Rm> // UMAAL<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UMAAL(Cond cond, Reg dHi, Reg dLo, Reg m, Reg n) { bool TranslatorVisitor::arm_UMAAL(Cond cond, Reg dHi, Reg dLo, Reg m, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -139,7 +139,7 @@ bool ArmTranslatorVisitor::arm_UMAAL(Cond cond, Reg dHi, Reg dLo, Reg m, Reg n)
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -155,7 +155,7 @@ bool ArmTranslatorVisitor::arm_UMAAL(Cond cond, Reg dHi, Reg dLo, Reg m, Reg n)
} }
// UMLAL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm> // UMLAL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) { bool TranslatorVisitor::arm_UMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -164,7 +164,7 @@ bool ArmTranslatorVisitor::arm_UMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -186,7 +186,7 @@ bool ArmTranslatorVisitor::arm_UMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
} }
// UMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm> // UMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) { bool TranslatorVisitor::arm_UMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -195,7 +195,7 @@ bool ArmTranslatorVisitor::arm_UMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -216,7 +216,7 @@ bool ArmTranslatorVisitor::arm_UMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
} }
// SMLAL<x><y><c> <RdLo>, <RdHi>, <Rn>, <Rm> // SMLAL<x><y><c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMLALxy(Cond cond, Reg dHi, Reg dLo, Reg m, bool M, bool N, Reg n) { bool TranslatorVisitor::arm_SMLALxy(Cond cond, Reg dHi, Reg dLo, Reg m, bool M, bool N, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -225,7 +225,7 @@ bool ArmTranslatorVisitor::arm_SMLALxy(Cond cond, Reg dHi, Reg dLo, Reg m, bool
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -245,12 +245,12 @@ bool ArmTranslatorVisitor::arm_SMLALxy(Cond cond, Reg dHi, Reg dLo, Reg m, bool
} }
// SMLA<x><y><c> <Rd>, <Rn>, <Rm>, <Ra> // SMLA<x><y><c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_SMLAxy(Cond cond, Reg d, Reg a, Reg m, bool M, bool N, Reg n) { bool TranslatorVisitor::arm_SMLAxy(Cond cond, Reg d, Reg a, Reg m, bool M, bool N, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -269,12 +269,12 @@ bool ArmTranslatorVisitor::arm_SMLAxy(Cond cond, Reg d, Reg a, Reg m, bool M, bo
} }
// SMUL<x><y><c> <Rd>, <Rn>, <Rm> // SMUL<x><y><c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMULxy(Cond cond, Reg d, Reg m, bool M, bool N, Reg n) { bool TranslatorVisitor::arm_SMULxy(Cond cond, Reg d, Reg m, bool M, bool N, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -291,12 +291,12 @@ bool ArmTranslatorVisitor::arm_SMULxy(Cond cond, Reg d, Reg m, bool M, bool N, R
} }
// SMLAW<y><c> <Rd>, <Rn>, <Rm>, <Ra> // SMLAW<y><c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_SMLAWy(Cond cond, Reg d, Reg a, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMLAWy(Cond cond, Reg d, Reg a, Reg m, bool M, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -315,12 +315,12 @@ bool ArmTranslatorVisitor::arm_SMLAWy(Cond cond, Reg d, Reg a, Reg m, bool M, Re
} }
// SMULW<y><c> <Rd>, <Rn>, <Rm> // SMULW<y><c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMULWy(Cond cond, Reg d, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMULWy(Cond cond, Reg d, Reg m, bool M, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -337,12 +337,12 @@ bool ArmTranslatorVisitor::arm_SMULWy(Cond cond, Reg d, Reg m, bool M, Reg n) {
} }
// SMMLA{R}<c> <Rd>, <Rn>, <Rm>, <Ra> // SMMLA{R}<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_SMMLA(Cond cond, Reg d, Reg a, Reg m, bool R, Reg n) { bool TranslatorVisitor::arm_SMMLA(Cond cond, Reg d, Reg a, Reg m, bool R, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC /* no check for a */) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC /* no check for a */) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -361,12 +361,12 @@ bool ArmTranslatorVisitor::arm_SMMLA(Cond cond, Reg d, Reg a, Reg m, bool R, Reg
} }
// SMMLS{R}<c> <Rd>, <Rn>, <Rm>, <Ra> // SMMLS{R}<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_SMMLS(Cond cond, Reg d, Reg a, Reg m, bool R, Reg n) { bool TranslatorVisitor::arm_SMMLS(Cond cond, Reg d, Reg a, Reg m, bool R, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -385,12 +385,12 @@ bool ArmTranslatorVisitor::arm_SMMLS(Cond cond, Reg d, Reg a, Reg m, bool R, Reg
} }
// SMMUL{R}<c> <Rd>, <Rn>, <Rm> // SMMUL{R}<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMMUL(Cond cond, Reg d, Reg m, bool R, Reg n) { bool TranslatorVisitor::arm_SMMUL(Cond cond, Reg d, Reg m, bool R, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -408,7 +408,7 @@ bool ArmTranslatorVisitor::arm_SMMUL(Cond cond, Reg d, Reg m, bool R, Reg n) {
} }
// SMLAD{X}<c> <Rd>, <Rn>, <Rm>, <Ra> // SMLAD{X}<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_SMLAD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMLAD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg n) {
if (a == Reg::PC) { if (a == Reg::PC) {
return arm_SMUAD(cond, d, m, M, n); return arm_SMUAD(cond, d, m, M, n);
} }
@ -417,7 +417,7 @@ bool ArmTranslatorVisitor::arm_SMLAD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -445,7 +445,7 @@ bool ArmTranslatorVisitor::arm_SMLAD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg
} }
// SMLALD{X}<c> <RdLo>, <RdHi>, <Rn>, <Rm> // SMLALD{X}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMLALD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMLALD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -454,7 +454,7 @@ bool ArmTranslatorVisitor::arm_SMLALD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -480,7 +480,7 @@ bool ArmTranslatorVisitor::arm_SMLALD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M
} }
// SMLSD{X}<c> <Rd>, <Rn>, <Rm>, <Ra> // SMLSD{X}<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_SMLSD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMLSD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg n) {
if (a == Reg::PC) { if (a == Reg::PC) {
return arm_SMUSD(cond, d, m, M, n); return arm_SMUSD(cond, d, m, M, n);
} }
@ -489,7 +489,7 @@ bool ArmTranslatorVisitor::arm_SMLSD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -516,7 +516,7 @@ bool ArmTranslatorVisitor::arm_SMLSD(Cond cond, Reg d, Reg a, Reg m, bool M, Reg
} }
// SMLSLD{X}<c> <RdLo>, <RdHi>, <Rn>, <Rm> // SMLSLD{X}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMLSLD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMLSLD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M, Reg n) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -525,7 +525,7 @@ bool ArmTranslatorVisitor::arm_SMLSLD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -551,12 +551,12 @@ bool ArmTranslatorVisitor::arm_SMLSLD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M
} }
// SMUAD{X}<c> <Rd>, <Rn>, <Rm> // SMUAD{X}<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMUAD(Cond cond, Reg d, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMUAD(Cond cond, Reg d, Reg m, bool M, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -581,12 +581,12 @@ bool ArmTranslatorVisitor::arm_SMUAD(Cond cond, Reg d, Reg m, bool M, Reg n) {
} }
// SMUSD{X}<c> <Rd>, <Rn>, <Rm> // SMUSD{X}<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SMUSD(Cond cond, Reg d, Reg m, bool M, Reg n) { bool TranslatorVisitor::arm_SMUSD(Cond cond, Reg d, Reg m, bool M, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// PKHBT<c> <Rd>, <Rn>, <Rm>{, LSL #<imm>} // PKHBT<c> <Rd>, <Rn>, <Rm>{, LSL #<imm>}
bool ArmTranslatorVisitor::arm_PKHBT(Cond cond, Reg n, Reg d, Imm<5> imm5, Reg m) { bool TranslatorVisitor::arm_PKHBT(Cond cond, Reg n, Reg d, Imm<5> imm5, Reg m) {
if (n == Reg::PC || d == Reg::PC || m == Reg::PC) { if (n == Reg::PC || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -26,12 +26,12 @@ bool ArmTranslatorVisitor::arm_PKHBT(Cond cond, Reg n, Reg d, Imm<5> imm5, Reg m
} }
// PKHTB<c> <Rd>, <Rn>, <Rm>{, ASR #<imm>} // PKHTB<c> <Rd>, <Rn>, <Rm>{, ASR #<imm>}
bool ArmTranslatorVisitor::arm_PKHTB(Cond cond, Reg n, Reg d, Imm<5> imm5, Reg m) { bool TranslatorVisitor::arm_PKHTB(Cond cond, Reg n, Reg d, Imm<5> imm5, Reg m) {
if (n == Reg::PC || d == Reg::PC || m == Reg::PC) { if (n == Reg::PC || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// SADD8<c> <Rd>, <Rn>, <Rm> // SADD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SADD8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SADD8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -24,12 +24,12 @@ bool ArmTranslatorVisitor::arm_SADD8(Cond cond, Reg n, Reg d, Reg m) {
} }
// SADD16<c> <Rd>, <Rn>, <Rm> // SADD16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SADD16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SADD16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -40,12 +40,12 @@ bool ArmTranslatorVisitor::arm_SADD16(Cond cond, Reg n, Reg d, Reg m) {
} }
// SASX<c> <Rd>, <Rn>, <Rm> // SASX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SASX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SASX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -56,12 +56,12 @@ bool ArmTranslatorVisitor::arm_SASX(Cond cond, Reg n, Reg d, Reg m) {
} }
// SSAX<c> <Rd>, <Rn>, <Rm> // SSAX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SSAX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SSAX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -72,12 +72,12 @@ bool ArmTranslatorVisitor::arm_SSAX(Cond cond, Reg n, Reg d, Reg m) {
} }
// SSUB8<c> <Rd>, <Rn>, <Rm> // SSUB8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SSUB8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SSUB8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -88,12 +88,12 @@ bool ArmTranslatorVisitor::arm_SSUB8(Cond cond, Reg n, Reg d, Reg m) {
} }
// SSUB16<c> <Rd>, <Rn>, <Rm> // SSUB16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SSUB16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SSUB16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -104,12 +104,12 @@ bool ArmTranslatorVisitor::arm_SSUB16(Cond cond, Reg n, Reg d, Reg m) {
} }
// UADD8<c> <Rd>, <Rn>, <Rm> // UADD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UADD8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UADD8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -120,12 +120,12 @@ bool ArmTranslatorVisitor::arm_UADD8(Cond cond, Reg n, Reg d, Reg m) {
} }
// UADD16<c> <Rd>, <Rn>, <Rm> // UADD16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UADD16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UADD16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -136,12 +136,12 @@ bool ArmTranslatorVisitor::arm_UADD16(Cond cond, Reg n, Reg d, Reg m) {
} }
// UASX<c> <Rd>, <Rn>, <Rm> // UASX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UASX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UASX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -152,12 +152,12 @@ bool ArmTranslatorVisitor::arm_UASX(Cond cond, Reg n, Reg d, Reg m) {
} }
// USAX<c> <Rd>, <Rn>, <Rm> // USAX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_USAX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_USAX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -168,12 +168,12 @@ bool ArmTranslatorVisitor::arm_USAX(Cond cond, Reg n, Reg d, Reg m) {
} }
// USAD8<c> <Rd>, <Rn>, <Rm> // USAD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_USAD8(Cond cond, Reg d, Reg m, Reg n) { bool TranslatorVisitor::arm_USAD8(Cond cond, Reg d, Reg m, Reg n) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -183,12 +183,12 @@ bool ArmTranslatorVisitor::arm_USAD8(Cond cond, Reg d, Reg m, Reg n) {
} }
// USADA8<c> <Rd>, <Rn>, <Rm>, <Ra> // USADA8<c> <Rd>, <Rn>, <Rm>, <Ra>
bool ArmTranslatorVisitor::arm_USADA8(Cond cond, Reg d, Reg a, Reg m, Reg n){ bool TranslatorVisitor::arm_USADA8(Cond cond, Reg d, Reg a, Reg m, Reg n){
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -199,12 +199,12 @@ bool ArmTranslatorVisitor::arm_USADA8(Cond cond, Reg d, Reg a, Reg m, Reg n){
} }
// USUB8<c> <Rd>, <Rn>, <Rm> // USUB8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_USUB8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_USUB8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -215,12 +215,12 @@ bool ArmTranslatorVisitor::arm_USUB8(Cond cond, Reg n, Reg d, Reg m) {
} }
// USUB16<c> <Rd>, <Rn>, <Rm> // USUB16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_USUB16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_USUB16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -233,12 +233,12 @@ bool ArmTranslatorVisitor::arm_USUB16(Cond cond, Reg n, Reg d, Reg m) {
// Parallel Add/Subtract (Saturating) instructions // Parallel Add/Subtract (Saturating) instructions
// QADD8<c> <Rd>, <Rn>, <Rm> // QADD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_QADD8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QADD8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -248,12 +248,12 @@ bool ArmTranslatorVisitor::arm_QADD8(Cond cond, Reg n, Reg d, Reg m) {
} }
// QADD16<c> <Rd>, <Rn>, <Rm> // QADD16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_QADD16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QADD16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -263,12 +263,12 @@ bool ArmTranslatorVisitor::arm_QADD16(Cond cond, Reg n, Reg d, Reg m) {
} }
// QSUB8<c> <Rd>, <Rn>, <Rm> // QSUB8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -278,12 +278,12 @@ bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
} }
// QSUB16<c> <Rd>, <Rn>, <Rm> // QSUB16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -293,12 +293,12 @@ bool ArmTranslatorVisitor::arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) {
} }
// UQADD8<c> <Rd>, <Rn>, <Rm> // UQADD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UQADD8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UQADD8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -308,12 +308,12 @@ bool ArmTranslatorVisitor::arm_UQADD8(Cond cond, Reg n, Reg d, Reg m) {
} }
// UQADD16<c> <Rd>, <Rn>, <Rm> // UQADD16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -323,12 +323,12 @@ bool ArmTranslatorVisitor::arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) {
} }
// UQSUB8<c> <Rd>, <Rn>, <Rm> // UQSUB8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -338,12 +338,12 @@ bool ArmTranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) {
} }
// UQSUB16<c> <Rd>, <Rn>, <Rm> // UQSUB16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UQSUB16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UQSUB16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -355,12 +355,12 @@ bool ArmTranslatorVisitor::arm_UQSUB16(Cond cond, Reg n, Reg d, Reg m) {
// Parallel Add/Subtract (Halving) instructions // Parallel Add/Subtract (Halving) instructions
// SHADD8<c> <Rd>, <Rn>, <Rm> // SHADD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SHADD8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SHADD8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -370,12 +370,12 @@ bool ArmTranslatorVisitor::arm_SHADD8(Cond cond, Reg n, Reg d, Reg m) {
} }
// SHADD16<c> <Rd>, <Rn>, <Rm> // SHADD16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SHADD16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SHADD16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -385,12 +385,12 @@ bool ArmTranslatorVisitor::arm_SHADD16(Cond cond, Reg n, Reg d, Reg m) {
} }
// SHASX<c> <Rd>, <Rn>, <Rm> // SHASX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SHASX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SHASX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -400,12 +400,12 @@ bool ArmTranslatorVisitor::arm_SHASX(Cond cond, Reg n, Reg d, Reg m) {
} }
// SHSAX<c> <Rd>, <Rn>, <Rm> // SHSAX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SHSAX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SHSAX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -415,12 +415,12 @@ bool ArmTranslatorVisitor::arm_SHSAX(Cond cond, Reg n, Reg d, Reg m) {
} }
// SHSUB8<c> <Rd>, <Rn>, <Rm> // SHSUB8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SHSUB8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SHSUB8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -430,12 +430,12 @@ bool ArmTranslatorVisitor::arm_SHSUB8(Cond cond, Reg n, Reg d, Reg m) {
} }
// SHSUB16<c> <Rd>, <Rn>, <Rm> // SHSUB16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_SHSUB16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_SHSUB16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -445,12 +445,12 @@ bool ArmTranslatorVisitor::arm_SHSUB16(Cond cond, Reg n, Reg d, Reg m) {
} }
// UHADD8<c> <Rd>, <Rn>, <Rm> // UHADD8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UHADD8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UHADD8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -460,12 +460,12 @@ bool ArmTranslatorVisitor::arm_UHADD8(Cond cond, Reg n, Reg d, Reg m) {
} }
// UHADD16<c> <Rd>, <Rn>, <Rm> // UHADD16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UHADD16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UHADD16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -475,12 +475,12 @@ bool ArmTranslatorVisitor::arm_UHADD16(Cond cond, Reg n, Reg d, Reg m) {
} }
// UHASX<c> <Rd>, <Rn>, <Rm> // UHASX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UHASX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UHASX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -490,12 +490,12 @@ bool ArmTranslatorVisitor::arm_UHASX(Cond cond, Reg n, Reg d, Reg m) {
} }
// UHSAX<c> <Rd>, <Rn>, <Rm> // UHSAX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UHSAX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UHSAX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -505,12 +505,12 @@ bool ArmTranslatorVisitor::arm_UHSAX(Cond cond, Reg n, Reg d, Reg m) {
} }
// UHSUB8<c> <Rd>, <Rn>, <Rm> // UHSUB8<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UHSUB8(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UHSUB8(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -520,12 +520,12 @@ bool ArmTranslatorVisitor::arm_UHSUB8(Cond cond, Reg n, Reg d, Reg m) {
} }
// UHSUB16<c> <Rd>, <Rn>, <Rm> // UHSUB16<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UHSUB16(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UHSUB16(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// RBIT<c> <Rd>, <Rm> // RBIT<c> <Rd>, <Rm>
bool ArmTranslatorVisitor::arm_RBIT(Cond cond, Reg d, Reg m) { bool TranslatorVisitor::arm_RBIT(Cond cond, Reg d, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -38,12 +38,12 @@ bool ArmTranslatorVisitor::arm_RBIT(Cond cond, Reg d, Reg m) {
} }
// REV<c> <Rd>, <Rm> // REV<c> <Rd>, <Rm>
bool ArmTranslatorVisitor::arm_REV(Cond cond, Reg d, Reg m) { bool TranslatorVisitor::arm_REV(Cond cond, Reg d, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -53,12 +53,12 @@ bool ArmTranslatorVisitor::arm_REV(Cond cond, Reg d, Reg m) {
} }
// REV16<c> <Rd>, <Rm> // REV16<c> <Rd>, <Rm>
bool ArmTranslatorVisitor::arm_REV16(Cond cond, Reg d, Reg m) { bool TranslatorVisitor::arm_REV16(Cond cond, Reg d, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -72,12 +72,12 @@ bool ArmTranslatorVisitor::arm_REV16(Cond cond, Reg d, Reg m) {
} }
// REVSH<c> <Rd>, <Rm> // REVSH<c> <Rd>, <Rm>
bool ArmTranslatorVisitor::arm_REVSH(Cond cond, Reg d, Reg m) { bool TranslatorVisitor::arm_REVSH(Cond cond, Reg d, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
@ -18,12 +18,12 @@ static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
// Saturation instructions // Saturation instructions
// SSAT<c> <Rd>, #<imm>, <Rn>{, <shift>} // SSAT<c> <Rd>, #<imm>, <Rn>{, <shift>}
bool ArmTranslatorVisitor::arm_SSAT(Cond cond, Imm<5> sat_imm, Reg d, Imm<5> imm5, bool sh, Reg n) { bool TranslatorVisitor::arm_SSAT(Cond cond, Imm<5> sat_imm, Reg d, Imm<5> imm5, bool sh, Reg n) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -38,12 +38,12 @@ bool ArmTranslatorVisitor::arm_SSAT(Cond cond, Imm<5> sat_imm, Reg d, Imm<5> imm
} }
// SSAT16<c> <Rd>, #<imm>, <Rn> // SSAT16<c> <Rd>, #<imm>, <Rn>
bool ArmTranslatorVisitor::arm_SSAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) { bool TranslatorVisitor::arm_SSAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -60,12 +60,12 @@ bool ArmTranslatorVisitor::arm_SSAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) {
} }
// USAT<c> <Rd>, #<imm5>, <Rn>{, <shift>} // USAT<c> <Rd>, #<imm5>, <Rn>{, <shift>}
bool ArmTranslatorVisitor::arm_USAT(Cond cond, Imm<5> sat_imm, Reg d, Imm<5> imm5, bool sh, Reg n) { bool TranslatorVisitor::arm_USAT(Cond cond, Imm<5> sat_imm, Reg d, Imm<5> imm5, bool sh, Reg n) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -80,12 +80,12 @@ bool ArmTranslatorVisitor::arm_USAT(Cond cond, Imm<5> sat_imm, Reg d, Imm<5> imm
} }
// USAT16<c> <Rd>, #<imm4>, <Rn> // USAT16<c> <Rd>, #<imm4>, <Rn>
bool ArmTranslatorVisitor::arm_USAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) { bool TranslatorVisitor::arm_USAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -105,12 +105,12 @@ bool ArmTranslatorVisitor::arm_USAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) {
// Saturated Add/Subtract instructions // Saturated Add/Subtract instructions
// QADD<c> <Rd>, <Rm>, <Rn> // QADD<c> <Rd>, <Rm>, <Rn>
bool ArmTranslatorVisitor::arm_QADD(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QADD(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -124,12 +124,12 @@ bool ArmTranslatorVisitor::arm_QADD(Cond cond, Reg n, Reg d, Reg m) {
} }
// QSUB<c> <Rd>, <Rm>, <Rn> // QSUB<c> <Rd>, <Rm>, <Rn>
bool ArmTranslatorVisitor::arm_QSUB(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QSUB(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -143,12 +143,12 @@ bool ArmTranslatorVisitor::arm_QSUB(Cond cond, Reg n, Reg d, Reg m) {
} }
// QDADD<c> <Rd>, <Rm>, <Rn> // QDADD<c> <Rd>, <Rm>, <Rn>
bool ArmTranslatorVisitor::arm_QDADD(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QDADD(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -164,12 +164,12 @@ bool ArmTranslatorVisitor::arm_QDADD(Cond cond, Reg n, Reg d, Reg m) {
} }
// QDSUB<c> <Rd>, <Rm>, <Rn> // QDSUB<c> <Rd>, <Rm>, <Rn>
bool ArmTranslatorVisitor::arm_QDSUB(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QDSUB(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -187,12 +187,12 @@ bool ArmTranslatorVisitor::arm_QDSUB(Cond cond, Reg n, Reg d, Reg m) {
// Parallel saturated instructions // Parallel saturated instructions
// QASX<c> <Rd>, <Rn>, <Rm> // QASX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -211,12 +211,12 @@ bool ArmTranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) {
} }
// QSAX<c> <Rd>, <Rn>, <Rm> // QSAX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -235,12 +235,12 @@ bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
} }
// UQASX<c> <Rd>, <Rn>, <Rm> // UQASX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -259,12 +259,12 @@ bool ArmTranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) {
} }
// UQSAX<c> <Rd>, <Rn>, <Rm> // UQSAX<c> <Rd>, <Rn>, <Rm>
bool ArmTranslatorVisitor::arm_UQSAX(Cond cond, Reg n, Reg d, Reg m) { bool TranslatorVisitor::arm_UQSAX(Cond cond, Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,24 +3,25 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// CPS<effect> <iflags>{, #<mode>} // CPS<effect> <iflags>{, #<mode>}
// CPS #<mode> // CPS #<mode>
bool ArmTranslatorVisitor::arm_CPS() { bool TranslatorVisitor::arm_CPS() {
return InterpretThisInstruction(); return InterpretThisInstruction();
} }
// MRS<c> <Rd>, <spec_reg> // MRS<c> <Rd>, <spec_reg>
bool ArmTranslatorVisitor::arm_MRS(Cond cond, Reg d) { bool TranslatorVisitor::arm_MRS(Cond cond, Reg d) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -29,10 +30,10 @@ bool ArmTranslatorVisitor::arm_MRS(Cond cond, Reg d) {
} }
// MSR<c> <spec_reg>, #<const> // MSR<c> <spec_reg>, #<const>
bool ArmTranslatorVisitor::arm_MSR_imm(Cond cond, int mask, int rotate, Imm<8> imm8) { bool TranslatorVisitor::arm_MSR_imm(Cond cond, int mask, int rotate, Imm<8> imm8) {
ASSERT_MSG(mask != 0, "Decode error"); ASSERT_MSG(mask != 0, "Decode error");
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -61,7 +62,7 @@ bool ArmTranslatorVisitor::arm_MSR_imm(Cond cond, int mask, int rotate, Imm<8> i
} }
// MSR<c> <spec_reg>, <Rn> // MSR<c> <spec_reg>, <Rn>
bool ArmTranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) { bool TranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) {
if (mask == 0) { if (mask == 0) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -70,7 +71,7 @@ bool ArmTranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -102,18 +103,18 @@ bool ArmTranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) {
} }
// RFE{<amode>} <Rn>{!} // RFE{<amode>} <Rn>{!}
bool ArmTranslatorVisitor::arm_RFE() { bool TranslatorVisitor::arm_RFE() {
return InterpretThisInstruction(); return InterpretThisInstruction();
} }
// SETEND <endian_specifier> // SETEND <endian_specifier>
bool ArmTranslatorVisitor::arm_SETEND(bool E) { bool TranslatorVisitor::arm_SETEND(bool E) {
ir.SetTerm(IR::Term::LinkBlock{ir.current_location.AdvancePC(4).SetEFlag(E)}); ir.SetTerm(IR::Term::LinkBlock{ir.current_location.AdvancePC(4).SetEFlag(E)});
return false; return false;
} }
// SRS{<amode>} SP{!}, #<mode> // SRS{<amode>} SP{!}, #<mode>
bool ArmTranslatorVisitor::arm_SRS() { bool TranslatorVisitor::arm_SRS() {
return InterpretThisInstruction(); return InterpretThisInstruction();
} }

View file

@ -3,24 +3,24 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// CLREX // CLREX
bool ArmTranslatorVisitor::arm_CLREX() { bool TranslatorVisitor::arm_CLREX() {
ir.ClearExclusive(); ir.ClearExclusive();
return true; return true;
} }
// SWP<c> <Rt>, <Rt2>, [<Rn>] // SWP<c> <Rt>, <Rt2>, [<Rn>]
// TODO: UNDEFINED if current mode is Hypervisor // TODO: UNDEFINED if current mode is Hypervisor
bool ArmTranslatorVisitor::arm_SWP(Cond cond, Reg n, Reg t, Reg t2) { bool TranslatorVisitor::arm_SWP(Cond cond, Reg n, Reg t, Reg t2) {
if (t == Reg::PC || t2 == Reg::PC || n == Reg::PC || n == t || n == t2) { if (t == Reg::PC || t2 == Reg::PC || n == Reg::PC || n == t || n == t2) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -33,12 +33,12 @@ bool ArmTranslatorVisitor::arm_SWP(Cond cond, Reg n, Reg t, Reg t2) {
// SWPB<c> <Rt>, <Rt2>, [<Rn>] // SWPB<c> <Rt>, <Rt2>, [<Rn>]
// TODO: UNDEFINED if current mode is Hypervisor // TODO: UNDEFINED if current mode is Hypervisor
bool ArmTranslatorVisitor::arm_SWPB(Cond cond, Reg n, Reg t, Reg t2) { bool TranslatorVisitor::arm_SWPB(Cond cond, Reg n, Reg t, Reg t2) {
if (t == Reg::PC || t2 == Reg::PC || n == Reg::PC || n == t || n == t2) { if (t == Reg::PC || t2 == Reg::PC || n == Reg::PC || n == t || n == t2) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -50,12 +50,12 @@ bool ArmTranslatorVisitor::arm_SWPB(Cond cond, Reg n, Reg t, Reg t2) {
} }
// LDA<c> <Rt>, [<Rn>] // LDA<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDA(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDA(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -64,12 +64,12 @@ bool ArmTranslatorVisitor::arm_LDA(Cond cond, Reg n, Reg t) {
return true; return true;
} }
// LDAB<c> <Rt>, [<Rn>] // LDAB<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDAB(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDAB(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -78,12 +78,12 @@ bool ArmTranslatorVisitor::arm_LDAB(Cond cond, Reg n, Reg t) {
return true; return true;
} }
// LDAH<c> <Rt>, [<Rn>] // LDAH<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDAH(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDAH(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -93,12 +93,12 @@ bool ArmTranslatorVisitor::arm_LDAH(Cond cond, Reg n, Reg t) {
} }
// LDAEX<c> <Rt>, [<Rn>] // LDAEX<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -108,12 +108,12 @@ bool ArmTranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) {
} }
// LDAEXB<c> <Rt>, [<Rn>] // LDAEXB<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -123,12 +123,12 @@ bool ArmTranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) {
} }
// LDAEXD<c> <Rt>, <Rt2>, [<Rn>] // LDAEXD<c> <Rt>, <Rt2>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) {
if (t == Reg::LR || t == Reg::PC || n == Reg::PC) { if (t == Reg::LR || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -141,12 +141,12 @@ bool ArmTranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) {
} }
// LDAEXH<c> <Rt>, [<Rn>] // LDAEXH<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -156,12 +156,12 @@ bool ArmTranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) {
} }
// STL<c> <Rt>, [<Rn>] // STL<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STL(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_STL(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -171,12 +171,12 @@ bool ArmTranslatorVisitor::arm_STL(Cond cond, Reg n, Reg t) {
} }
// STLB<c> <Rt>, [<Rn>] // STLB<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STLB(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_STLB(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -186,12 +186,12 @@ bool ArmTranslatorVisitor::arm_STLB(Cond cond, Reg n, Reg t) {
} }
// STLH<c> <Rd>, <Rt>, [<Rn>] // STLH<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STLH(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_STLH(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -201,7 +201,7 @@ bool ArmTranslatorVisitor::arm_STLH(Cond cond, Reg n, Reg t) {
} }
// STLEXB<c> <Rd>, <Rt>, [<Rn>] // STLEXB<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::PC) { if (n == Reg::PC || d == Reg::PC || t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -210,7 +210,7 @@ bool ArmTranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -221,7 +221,7 @@ bool ArmTranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) {
return true; return true;
} }
// STLEXD<c> <Rd>, <Rt>, <Rt2>, [<Rn>] // STLEXD<c> <Rd>, <Rt>, <Rt2>, [<Rn>]
bool ArmTranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::LR || static_cast<size_t>(t) % 2 == 1) { if (n == Reg::PC || d == Reg::PC || t == Reg::LR || static_cast<size_t>(t) % 2 == 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -230,7 +230,7 @@ bool ArmTranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -244,7 +244,7 @@ bool ArmTranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) {
} }
// STLEXH<c> <Rd>, <Rt>, [<Rn>] // STLEXH<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::PC) { if (n == Reg::PC || d == Reg::PC || t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -253,7 +253,7 @@ bool ArmTranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -265,7 +265,7 @@ bool ArmTranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) {
} }
// STLEX<c> <Rd>, <Rt>, [<Rn>] // STLEX<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::PC) { if (n == Reg::PC || d == Reg::PC || t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -274,7 +274,7 @@ bool ArmTranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -286,12 +286,12 @@ bool ArmTranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) {
} }
// LDREX<c> <Rt>, [<Rn>] // LDREX<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDREX(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDREX(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -301,12 +301,12 @@ bool ArmTranslatorVisitor::arm_LDREX(Cond cond, Reg n, Reg t) {
} }
// LDREXB<c> <Rt>, [<Rn>] // LDREXB<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDREXB(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDREXB(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -316,12 +316,12 @@ bool ArmTranslatorVisitor::arm_LDREXB(Cond cond, Reg n, Reg t) {
} }
// LDREXD<c> <Rt>, <Rt2>, [<Rn>] // LDREXD<c> <Rt>, <Rt2>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDREXD(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDREXD(Cond cond, Reg n, Reg t) {
if (t == Reg::LR || t == Reg::PC || n == Reg::PC) { if (t == Reg::LR || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -334,12 +334,12 @@ bool ArmTranslatorVisitor::arm_LDREXD(Cond cond, Reg n, Reg t) {
} }
// LDREXH<c> <Rt>, [<Rn>] // LDREXH<c> <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_LDREXH(Cond cond, Reg n, Reg t) { bool TranslatorVisitor::arm_LDREXH(Cond cond, Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -349,7 +349,7 @@ bool ArmTranslatorVisitor::arm_LDREXH(Cond cond, Reg n, Reg t) {
} }
// STREX<c> <Rd>, <Rt>, [<Rn>] // STREX<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::PC) { if (n == Reg::PC || d == Reg::PC || t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -358,7 +358,7 @@ bool ArmTranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -370,7 +370,7 @@ bool ArmTranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) {
} }
// STREXB<c> <Rd>, <Rt>, [<Rn>] // STREXB<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::PC) { if (n == Reg::PC || d == Reg::PC || t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -379,7 +379,7 @@ bool ArmTranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -391,7 +391,7 @@ bool ArmTranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) {
} }
// STREXD<c> <Rd>, <Rt>, <Rt2>, [<Rn>] // STREXD<c> <Rd>, <Rt>, <Rt2>, [<Rn>]
bool ArmTranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::LR || static_cast<size_t>(t) % 2 == 1) { if (n == Reg::PC || d == Reg::PC || t == Reg::LR || static_cast<size_t>(t) % 2 == 1) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -400,7 +400,7 @@ bool ArmTranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }
@ -414,7 +414,7 @@ bool ArmTranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) {
} }
// STREXH<c> <Rd>, <Rt>, [<Rn>] // STREXH<c> <Rd>, <Rt>, [<Rn>]
bool ArmTranslatorVisitor::arm_STREXH(Cond cond, Reg n, Reg d, Reg t) { bool TranslatorVisitor::arm_STREXH(Cond cond, Reg n, Reg d, Reg t) {
if (n == Reg::PC || d == Reg::PC || t == Reg::PC) { if (n == Reg::PC || d == Reg::PC || t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -423,7 +423,7 @@ bool ArmTranslatorVisitor::arm_STREXH(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!ArmConditionPassed(cond)) {
return true; return true;
} }

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include <dynarmic/A32/config.h> #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/impl/translate_thumb.h" #include <dynarmic/A32/config.h>
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// LSLS <Rd>, <Rm>, #<imm5> // LSLS <Rd>, <Rm>, #<imm5>
bool ThumbTranslatorVisitor::thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d) { bool TranslatorVisitor::thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d) {
const u8 shift_n = imm5.ZeroExtend<u8>(); const u8 shift_n = imm5.ZeroExtend<u8>();
if (shift_n == 0 && ir.current_location.IT().IsInITBlock()) { if (shift_n == 0 && ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -29,7 +29,7 @@ bool ThumbTranslatorVisitor::thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d) {
} }
// LSRS <Rd>, <Rm>, #<imm5> // LSRS <Rd>, <Rm>, #<imm5>
bool ThumbTranslatorVisitor::thumb16_LSR_imm(Imm<5> imm5, Reg m, Reg d) { bool TranslatorVisitor::thumb16_LSR_imm(Imm<5> imm5, Reg m, Reg d) {
const u8 shift_n = imm5 != 0 ? imm5.ZeroExtend<u8>() : u8(32); const u8 shift_n = imm5 != 0 ? imm5.ZeroExtend<u8>() : u8(32);
const auto cpsr_c = ir.GetCFlag(); const auto cpsr_c = ir.GetCFlag();
const auto result = ir.LogicalShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); const auto result = ir.LogicalShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c);
@ -44,7 +44,7 @@ bool ThumbTranslatorVisitor::thumb16_LSR_imm(Imm<5> imm5, Reg m, Reg d) {
} }
// ASRS <Rd>, <Rm>, #<imm5> // ASRS <Rd>, <Rm>, #<imm5>
bool ThumbTranslatorVisitor::thumb16_ASR_imm(Imm<5> imm5, Reg m, Reg d) { bool TranslatorVisitor::thumb16_ASR_imm(Imm<5> imm5, Reg m, Reg d) {
const u8 shift_n = imm5 != 0 ? imm5.ZeroExtend<u8>() : u8(32); const u8 shift_n = imm5 != 0 ? imm5.ZeroExtend<u8>() : u8(32);
const auto cpsr_c = ir.GetCFlag(); const auto cpsr_c = ir.GetCFlag();
const auto result = ir.ArithmeticShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c); const auto result = ir.ArithmeticShiftRight(ir.GetRegister(m), ir.Imm8(shift_n), cpsr_c);
@ -60,7 +60,7 @@ bool ThumbTranslatorVisitor::thumb16_ASR_imm(Imm<5> imm5, Reg m, Reg d) {
// ADDS <Rd>, <Rn>, <Rm> // ADDS <Rd>, <Rn>, <Rm>
// Note that it is not possible to encode Rd == R15. // Note that it is not possible to encode Rd == R15.
bool ThumbTranslatorVisitor::thumb16_ADD_reg_t1(Reg m, Reg n, Reg d) { bool TranslatorVisitor::thumb16_ADD_reg_t1(Reg m, Reg n, Reg d) {
const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0));
ir.SetRegister(d, result.result); ir.SetRegister(d, result.result);
@ -75,7 +75,7 @@ bool ThumbTranslatorVisitor::thumb16_ADD_reg_t1(Reg m, Reg n, Reg d) {
// SUBS <Rd>, <Rn>, <Rm> // SUBS <Rd>, <Rn>, <Rm>
// Note that it is not possible to encode Rd == R15. // Note that it is not possible to encode Rd == R15.
bool ThumbTranslatorVisitor::thumb16_SUB_reg(Reg m, Reg n, Reg d) { bool TranslatorVisitor::thumb16_SUB_reg(Reg m, Reg n, Reg d) {
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
ir.SetRegister(d, result.result); ir.SetRegister(d, result.result);
@ -90,7 +90,7 @@ bool ThumbTranslatorVisitor::thumb16_SUB_reg(Reg m, Reg n, Reg d) {
// ADDS <Rd>, <Rn>, #<imm3> // ADDS <Rd>, <Rn>, #<imm3>
// Rd can never encode R15. // Rd can never encode R15.
bool ThumbTranslatorVisitor::thumb16_ADD_imm_t1(Imm<3> imm3, Reg n, Reg d) { bool TranslatorVisitor::thumb16_ADD_imm_t1(Imm<3> imm3, Reg n, Reg d) {
const u32 imm32 = imm3.ZeroExtend(); const u32 imm32 = imm3.ZeroExtend();
const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(0)); const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(0));
@ -106,7 +106,7 @@ bool ThumbTranslatorVisitor::thumb16_ADD_imm_t1(Imm<3> imm3, Reg n, Reg d) {
// SUBS <Rd>, <Rn>, #<imm3> // SUBS <Rd>, <Rn>, #<imm3>
// Rd can never encode R15. // Rd can never encode R15.
bool ThumbTranslatorVisitor::thumb16_SUB_imm_t1(Imm<3> imm3, Reg n, Reg d) { bool TranslatorVisitor::thumb16_SUB_imm_t1(Imm<3> imm3, Reg n, Reg d) {
const u32 imm32 = imm3.ZeroExtend(); const u32 imm32 = imm3.ZeroExtend();
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
@ -122,7 +122,7 @@ bool ThumbTranslatorVisitor::thumb16_SUB_imm_t1(Imm<3> imm3, Reg n, Reg d) {
// MOVS <Rd>, #<imm8> // MOVS <Rd>, #<imm8>
// Rd can never encode R15. // Rd can never encode R15.
bool ThumbTranslatorVisitor::thumb16_MOV_imm(Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb16_MOV_imm(Reg d, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend(); const u32 imm32 = imm8.ZeroExtend();
const auto result = ir.Imm32(imm32); const auto result = ir.Imm32(imm32);
@ -135,7 +135,7 @@ bool ThumbTranslatorVisitor::thumb16_MOV_imm(Reg d, Imm<8> imm8) {
} }
// CMP <Rn>, #<imm8> // CMP <Rn>, #<imm8>
bool ThumbTranslatorVisitor::thumb16_CMP_imm(Reg n, Imm<8> imm8) { bool TranslatorVisitor::thumb16_CMP_imm(Reg n, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend(); const u32 imm32 = imm8.ZeroExtend();
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1)); const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.Imm32(imm32), ir.Imm1(1));
@ -148,7 +148,7 @@ bool ThumbTranslatorVisitor::thumb16_CMP_imm(Reg n, Imm<8> imm8) {
// ADDS <Rdn>, #<imm8> // ADDS <Rdn>, #<imm8>
// Rd can never encode R15. // Rd can never encode R15.
bool ThumbTranslatorVisitor::thumb16_ADD_imm_t2(Reg d_n, Imm<8> imm8) { bool TranslatorVisitor::thumb16_ADD_imm_t2(Reg d_n, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend(); const u32 imm32 = imm8.ZeroExtend();
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
@ -166,7 +166,7 @@ bool ThumbTranslatorVisitor::thumb16_ADD_imm_t2(Reg d_n, Imm<8> imm8) {
// SUBS <Rd>, <Rn>, #<imm3> // SUBS <Rd>, <Rn>, #<imm3>
// Rd can never encode R15. // Rd can never encode R15.
bool ThumbTranslatorVisitor::thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8) { bool TranslatorVisitor::thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend(); const u32 imm32 = imm8.ZeroExtend();
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
@ -184,7 +184,7 @@ bool ThumbTranslatorVisitor::thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8) {
// ANDS <Rdn>, <Rm> // ANDS <Rdn>, <Rm>
// Note that it is not possible to encode Rdn == R15. // Note that it is not possible to encode Rdn == R15.
bool ThumbTranslatorVisitor::thumb16_AND_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_AND_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); const auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m));
@ -199,7 +199,7 @@ bool ThumbTranslatorVisitor::thumb16_AND_reg(Reg m, Reg d_n) {
// EORS <Rdn>, <Rm> // EORS <Rdn>, <Rm>
// Note that it is not possible to encode Rdn == R15. // Note that it is not possible to encode Rdn == R15.
bool ThumbTranslatorVisitor::thumb16_EOR_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_EOR_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto result = ir.Eor(ir.GetRegister(n), ir.GetRegister(m)); const auto result = ir.Eor(ir.GetRegister(n), ir.GetRegister(m));
@ -213,7 +213,7 @@ bool ThumbTranslatorVisitor::thumb16_EOR_reg(Reg m, Reg d_n) {
} }
// LSLS <Rdn>, <Rm> // LSLS <Rdn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_LSL_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_LSL_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m));
@ -230,7 +230,7 @@ bool ThumbTranslatorVisitor::thumb16_LSL_reg(Reg m, Reg d_n) {
} }
// LSRS <Rdn>, <Rm> // LSRS <Rdn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_LSR_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_LSR_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m));
@ -247,7 +247,7 @@ bool ThumbTranslatorVisitor::thumb16_LSR_reg(Reg m, Reg d_n) {
} }
// ASRS <Rdn>, <Rm> // ASRS <Rdn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_ASR_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_ASR_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m));
@ -265,7 +265,7 @@ bool ThumbTranslatorVisitor::thumb16_ASR_reg(Reg m, Reg d_n) {
// ADCS <Rdn>, <Rm> // ADCS <Rdn>, <Rm>
// Note that it is not possible to encode Rd == R15. // Note that it is not possible to encode Rd == R15.
bool ThumbTranslatorVisitor::thumb16_ADC_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_ADC_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto aspr_c = ir.GetCFlag(); const auto aspr_c = ir.GetCFlag();
@ -283,7 +283,7 @@ bool ThumbTranslatorVisitor::thumb16_ADC_reg(Reg m, Reg d_n) {
// SBCS <Rdn>, <Rm> // SBCS <Rdn>, <Rm>
// Note that it is not possible to encode Rd == R15. // Note that it is not possible to encode Rd == R15.
bool ThumbTranslatorVisitor::thumb16_SBC_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_SBC_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto aspr_c = ir.GetCFlag(); const auto aspr_c = ir.GetCFlag();
@ -300,7 +300,7 @@ bool ThumbTranslatorVisitor::thumb16_SBC_reg(Reg m, Reg d_n) {
} }
// RORS <Rdn>, <Rm> // RORS <Rdn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_ROR_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_ROR_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m)); const auto shift_n = ir.LeastSignificantByte(ir.GetRegister(m));
@ -317,7 +317,7 @@ bool ThumbTranslatorVisitor::thumb16_ROR_reg(Reg m, Reg d_n) {
} }
// TST <Rn>, <Rm> // TST <Rn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_TST_reg(Reg m, Reg n) { bool TranslatorVisitor::thumb16_TST_reg(Reg m, Reg n) {
const auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m)); const auto result = ir.And(ir.GetRegister(n), ir.GetRegister(m));
ir.SetNFlag(ir.MostSignificantBit(result)); ir.SetNFlag(ir.MostSignificantBit(result));
ir.SetZFlag(ir.IsZero(result)); ir.SetZFlag(ir.IsZero(result));
@ -326,7 +326,7 @@ bool ThumbTranslatorVisitor::thumb16_TST_reg(Reg m, Reg n) {
// RSBS <Rd>, <Rn>, #0 // RSBS <Rd>, <Rn>, #0
// Rd can never encode R15. // Rd can never encode R15.
bool ThumbTranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) { bool TranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
const auto result = ir.SubWithCarry(ir.Imm32(0), ir.GetRegister(n), ir.Imm1(1)); const auto result = ir.SubWithCarry(ir.Imm32(0), ir.GetRegister(n), ir.Imm1(1));
ir.SetRegister(d, result.result); ir.SetRegister(d, result.result);
if (!ir.current_location.IT().IsInITBlock()) { if (!ir.current_location.IT().IsInITBlock()) {
@ -339,7 +339,7 @@ bool ThumbTranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
} }
// CMP <Rn>, <Rm> // CMP <Rn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_CMP_reg_t1(Reg m, Reg n) { bool TranslatorVisitor::thumb16_CMP_reg_t1(Reg m, Reg n) {
const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1)); const auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result)); ir.SetZFlag(ir.IsZero(result.result));
@ -349,7 +349,7 @@ bool ThumbTranslatorVisitor::thumb16_CMP_reg_t1(Reg m, Reg n) {
} }
// CMN <Rn>, <Rm> // CMN <Rn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_CMN_reg(Reg m, Reg n) { bool TranslatorVisitor::thumb16_CMN_reg(Reg m, Reg n) {
const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0)); const auto result = ir.AddWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(0));
ir.SetNFlag(ir.MostSignificantBit(result.result)); ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result)); ir.SetZFlag(ir.IsZero(result.result));
@ -360,7 +360,7 @@ bool ThumbTranslatorVisitor::thumb16_CMN_reg(Reg m, Reg n) {
// ORRS <Rdn>, <Rm> // ORRS <Rdn>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_ORR_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_ORR_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto result = ir.Or(ir.GetRegister(m), ir.GetRegister(n)); const auto result = ir.Or(ir.GetRegister(m), ir.GetRegister(n));
@ -375,7 +375,7 @@ bool ThumbTranslatorVisitor::thumb16_ORR_reg(Reg m, Reg d_n) {
// MULS <Rdn>, <Rm>, <Rdn> // MULS <Rdn>, <Rm>, <Rdn>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_MUL_reg(Reg n, Reg d_m) { bool TranslatorVisitor::thumb16_MUL_reg(Reg n, Reg d_m) {
const Reg d = d_m; const Reg d = d_m;
const Reg m = d_m; const Reg m = d_m;
const auto result = ir.Mul(ir.GetRegister(m), ir.GetRegister(n)); const auto result = ir.Mul(ir.GetRegister(m), ir.GetRegister(n));
@ -390,7 +390,7 @@ bool ThumbTranslatorVisitor::thumb16_MUL_reg(Reg n, Reg d_m) {
// BICS <Rdn>, <Rm> // BICS <Rdn>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_BIC_reg(Reg m, Reg d_n) { bool TranslatorVisitor::thumb16_BIC_reg(Reg m, Reg d_n) {
const Reg d = d_n; const Reg d = d_n;
const Reg n = d_n; const Reg n = d_n;
const auto result = ir.And(ir.GetRegister(n), ir.Not(ir.GetRegister(m))); const auto result = ir.And(ir.GetRegister(n), ir.Not(ir.GetRegister(m)));
@ -405,7 +405,7 @@ bool ThumbTranslatorVisitor::thumb16_BIC_reg(Reg m, Reg d_n) {
// MVNS <Rd>, <Rm> // MVNS <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_MVN_reg(Reg m, Reg d) { bool TranslatorVisitor::thumb16_MVN_reg(Reg m, Reg d) {
const auto result = ir.Not(ir.GetRegister(m)); const auto result = ir.Not(ir.GetRegister(m));
ir.SetRegister(d, result); ir.SetRegister(d, result);
@ -417,7 +417,7 @@ bool ThumbTranslatorVisitor::thumb16_MVN_reg(Reg m, Reg d) {
} }
// ADD <Rdn>, <Rm> // ADD <Rdn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_ADD_reg_t2(bool d_n_hi, Reg m, Reg d_n_lo) { bool TranslatorVisitor::thumb16_ADD_reg_t2(bool d_n_hi, Reg m, Reg d_n_lo) {
const Reg d_n = d_n_hi ? (d_n_lo + 8) : d_n_lo; const Reg d_n = d_n_hi ? (d_n_lo + 8) : d_n_lo;
const Reg n = d_n; const Reg n = d_n;
const Reg d = d_n; const Reg d = d_n;
@ -442,7 +442,7 @@ bool ThumbTranslatorVisitor::thumb16_ADD_reg_t2(bool d_n_hi, Reg m, Reg d_n_lo)
} }
// CMP <Rn>, <Rm> // CMP <Rn>, <Rm>
bool ThumbTranslatorVisitor::thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) { bool TranslatorVisitor::thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) {
const Reg n = n_hi ? (n_lo + 8) : n_lo; const Reg n = n_hi ? (n_lo + 8) : n_lo;
if (n < Reg::R8 && m < Reg::R8) { if (n < Reg::R8 && m < Reg::R8) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -460,7 +460,7 @@ bool ThumbTranslatorVisitor::thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) {
} }
// MOV <Rd>, <Rm> // MOV <Rd>, <Rm>
bool ThumbTranslatorVisitor::thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) { bool TranslatorVisitor::thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) {
const Reg d = d_hi ? (d_lo + 8) : d_lo; const Reg d = d_hi ? (d_lo + 8) : d_lo;
if (d == Reg::PC && ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) { if (d == Reg::PC && ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -481,7 +481,7 @@ bool ThumbTranslatorVisitor::thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) {
// LDR <Rt>, <label> // LDR <Rt>, <label>
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDR_literal(Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb16_LDR_literal(Reg t, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const u32 address = ir.AlignPC(4) + imm32; const u32 address = ir.AlignPC(4) + imm32;
const auto data = ir.ReadMemory32(ir.Imm32(address)); const auto data = ir.ReadMemory32(ir.Imm32(address));
@ -492,7 +492,7 @@ bool ThumbTranslatorVisitor::thumb16_LDR_literal(Reg t, Imm<8> imm8) {
// STR <Rt>, [<Rn>, <Rm>] // STR <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_STR_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_STR_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.GetRegister(t); const auto data = ir.GetRegister(t);
@ -502,7 +502,7 @@ bool ThumbTranslatorVisitor::thumb16_STR_reg(Reg m, Reg n, Reg t) {
// STRH <Rt>, [<Rn>, <Rm>] // STRH <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_STRH_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_STRH_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto data = ir.LeastSignificantHalf(ir.GetRegister(t));
@ -512,7 +512,7 @@ bool ThumbTranslatorVisitor::thumb16_STRH_reg(Reg m, Reg n, Reg t) {
// STRB <Rt>, [<Rn>, <Rm>] // STRB <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_STRB_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_STRB_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.LeastSignificantByte(ir.GetRegister(t)); const auto data = ir.LeastSignificantByte(ir.GetRegister(t));
@ -522,7 +522,7 @@ bool ThumbTranslatorVisitor::thumb16_STRB_reg(Reg m, Reg n, Reg t) {
// LDRSB <Rt>, [<Rn>, <Rm>] // LDRSB <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDRSB_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRSB_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.SignExtendByteToWord(ir.ReadMemory8(address));
@ -532,7 +532,7 @@ bool ThumbTranslatorVisitor::thumb16_LDRSB_reg(Reg m, Reg n, Reg t) {
// LDR <Rt>, [<Rn>, <Rm>] // LDR <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address);
@ -542,7 +542,7 @@ bool ThumbTranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) {
// LDRH <Rt>, [<Rn>, <Rm>] // LDRH <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDRH_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRH_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address));
@ -552,7 +552,7 @@ bool ThumbTranslatorVisitor::thumb16_LDRH_reg(Reg m, Reg n, Reg t) {
// LDRB <Rt>, [<Rn>, <Rm>] // LDRB <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDRB_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRB_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address));
@ -562,7 +562,7 @@ bool ThumbTranslatorVisitor::thumb16_LDRB_reg(Reg m, Reg n, Reg t) {
// LDRH <Rt>, [<Rn>, <Rm>] // LDRH <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDRSH_reg(Reg m, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRSH_reg(Reg m, Reg n, Reg t) {
const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m)); const auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.SignExtendHalfToWord(ir.ReadMemory16(address));
@ -572,7 +572,7 @@ bool ThumbTranslatorVisitor::thumb16_LDRSH_reg(Reg m, Reg n, Reg t) {
// STR <Rt>, [<Rn>, #<imm>] // STR <Rt>, [<Rn>, #<imm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend() << 2; const u32 imm32 = imm5.ZeroExtend() << 2;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.GetRegister(t); const auto data = ir.GetRegister(t);
@ -583,7 +583,7 @@ bool ThumbTranslatorVisitor::thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
// LDR <Rt>, [<Rn>, #<imm>] // LDR <Rt>, [<Rn>, #<imm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend() << 2; const u32 imm32 = imm5.ZeroExtend() << 2;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ReadMemory32(address); const auto data = ir.ReadMemory32(address);
@ -594,7 +594,7 @@ bool ThumbTranslatorVisitor::thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t) {
// STRB <Rt>, [<Rn>, #<imm>] // STRB <Rt>, [<Rn>, #<imm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend(); const u32 imm32 = imm5.ZeroExtend();
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.LeastSignificantByte(ir.GetRegister(t)); const auto data = ir.LeastSignificantByte(ir.GetRegister(t));
@ -605,7 +605,7 @@ bool ThumbTranslatorVisitor::thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t) {
// LDRB <Rt>, [<Rn>, #<imm>] // LDRB <Rt>, [<Rn>, #<imm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend(); const u32 imm32 = imm5.ZeroExtend();
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address)); const auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address));
@ -615,7 +615,7 @@ bool ThumbTranslatorVisitor::thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t) {
} }
// STRH <Rt>, [<Rn>, #<imm5>] // STRH <Rt>, [<Rn>, #<imm5>]
bool ThumbTranslatorVisitor::thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend() << 1; const u32 imm32 = imm5.ZeroExtend() << 1;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.LeastSignificantHalf(ir.GetRegister(t)); const auto data = ir.LeastSignificantHalf(ir.GetRegister(t));
@ -625,7 +625,7 @@ bool ThumbTranslatorVisitor::thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t) {
} }
// LDRH <Rt>, [<Rn>, #<imm5>] // LDRH <Rt>, [<Rn>, #<imm5>]
bool ThumbTranslatorVisitor::thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t) { bool TranslatorVisitor::thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t) {
const u32 imm32 = imm5.ZeroExtend() << 1; const u32 imm32 = imm5.ZeroExtend() << 1;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address)); const auto data = ir.ZeroExtendHalfToWord(ir.ReadMemory16(address));
@ -636,7 +636,7 @@ bool ThumbTranslatorVisitor::thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t) {
// STR <Rt>, [<Rn>, #<imm>] // STR <Rt>, [<Rn>, #<imm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_STR_imm_t2(Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb16_STR_imm_t2(Reg t, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const Reg n = Reg::SP; const Reg n = Reg::SP;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
@ -648,7 +648,7 @@ bool ThumbTranslatorVisitor::thumb16_STR_imm_t2(Reg t, Imm<8> imm8) {
// LDR <Rt>, [<Rn>, #<imm>] // LDR <Rt>, [<Rn>, #<imm>]
// Rt cannot encode R15. // Rt cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_LDR_imm_t2(Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb16_LDR_imm_t2(Reg t, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const Reg n = Reg::SP; const Reg n = Reg::SP;
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32)); const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
@ -660,7 +660,7 @@ bool ThumbTranslatorVisitor::thumb16_LDR_imm_t2(Reg t, Imm<8> imm8) {
// ADR <Rd>, <label> // ADR <Rd>, <label>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_ADR(Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb16_ADR(Reg d, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const auto result = ir.Imm32(ir.AlignPC(4) + imm32); const auto result = ir.Imm32(ir.AlignPC(4) + imm32);
@ -669,7 +669,7 @@ bool ThumbTranslatorVisitor::thumb16_ADR(Reg d, Imm<8> imm8) {
} }
// ADD <Rd>, SP, #<imm> // ADD <Rd>, SP, #<imm>
bool ThumbTranslatorVisitor::thumb16_ADD_sp_t1(Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb16_ADD_sp_t1(Reg d, Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend() << 2; const u32 imm32 = imm8.ZeroExtend() << 2;
const auto result = ir.AddWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(0)); const auto result = ir.AddWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(0));
@ -678,7 +678,7 @@ bool ThumbTranslatorVisitor::thumb16_ADD_sp_t1(Reg d, Imm<8> imm8) {
} }
// ADD SP, SP, #<imm> // ADD SP, SP, #<imm>
bool ThumbTranslatorVisitor::thumb16_ADD_sp_t2(Imm<7> imm7) { bool TranslatorVisitor::thumb16_ADD_sp_t2(Imm<7> imm7) {
const u32 imm32 = imm7.ZeroExtend() << 2; const u32 imm32 = imm7.ZeroExtend() << 2;
const Reg d = Reg::SP; const Reg d = Reg::SP;
const auto result = ir.AddWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(0)); const auto result = ir.AddWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(0));
@ -688,7 +688,7 @@ bool ThumbTranslatorVisitor::thumb16_ADD_sp_t2(Imm<7> imm7) {
} }
// SUB SP, SP, #<imm> // SUB SP, SP, #<imm>
bool ThumbTranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) { bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
const u32 imm32 = imm7.ZeroExtend() << 2; const u32 imm32 = imm7.ZeroExtend() << 2;
const Reg d = Reg::SP; const Reg d = Reg::SP;
const auto result = ir.SubWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(1)); const auto result = ir.SubWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(1));
@ -698,7 +698,7 @@ bool ThumbTranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
} }
// SEV<c> // SEV<c>
bool ThumbTranslatorVisitor::thumb16_SEV() { bool TranslatorVisitor::thumb16_SEV() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -706,7 +706,7 @@ bool ThumbTranslatorVisitor::thumb16_SEV() {
} }
// SEVL<c> // SEVL<c>
bool ThumbTranslatorVisitor::thumb16_SEVL() { bool TranslatorVisitor::thumb16_SEVL() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -714,7 +714,7 @@ bool ThumbTranslatorVisitor::thumb16_SEVL() {
} }
// WFE<c> // WFE<c>
bool ThumbTranslatorVisitor::thumb16_WFE() { bool TranslatorVisitor::thumb16_WFE() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -722,7 +722,7 @@ bool ThumbTranslatorVisitor::thumb16_WFE() {
} }
// WFI<c> // WFI<c>
bool ThumbTranslatorVisitor::thumb16_WFI() { bool TranslatorVisitor::thumb16_WFI() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -730,7 +730,7 @@ bool ThumbTranslatorVisitor::thumb16_WFI() {
} }
// YIELD<c> // YIELD<c>
bool ThumbTranslatorVisitor::thumb16_YIELD() { bool TranslatorVisitor::thumb16_YIELD() {
if (!options.hook_hint_instructions) { if (!options.hook_hint_instructions) {
return true; return true;
} }
@ -738,12 +738,12 @@ bool ThumbTranslatorVisitor::thumb16_YIELD() {
} }
// NOP<c> // NOP<c>
bool ThumbTranslatorVisitor::thumb16_NOP() { bool TranslatorVisitor::thumb16_NOP() {
return true; return true;
} }
// IT{<x>{<y>{<z>}}} <cond> // IT{<x>{<y>{<z>}}} <cond>
bool ThumbTranslatorVisitor::thumb16_IT(Imm<8> imm8) { bool TranslatorVisitor::thumb16_IT(Imm<8> imm8) {
ASSERT_MSG((imm8.Bits<0, 3>() != 0b0000), "Decode Error"); ASSERT_MSG((imm8.Bits<0, 3>() != 0b0000), "Decode Error");
if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && Common::BitCount(imm8.Bits<0, 3>()) != 1)) { if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && Common::BitCount(imm8.Bits<0, 3>()) != 1)) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -759,7 +759,7 @@ bool ThumbTranslatorVisitor::thumb16_IT(Imm<8> imm8) {
// SXTH <Rd>, <Rm> // SXTH <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_SXTH(Reg m, Reg d) { bool TranslatorVisitor::thumb16_SXTH(Reg m, Reg d) {
const auto half = ir.LeastSignificantHalf(ir.GetRegister(m)); const auto half = ir.LeastSignificantHalf(ir.GetRegister(m));
ir.SetRegister(d, ir.SignExtendHalfToWord(half)); ir.SetRegister(d, ir.SignExtendHalfToWord(half));
return true; return true;
@ -767,7 +767,7 @@ bool ThumbTranslatorVisitor::thumb16_SXTH(Reg m, Reg d) {
// SXTB <Rd>, <Rm> // SXTB <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_SXTB(Reg m, Reg d) { bool TranslatorVisitor::thumb16_SXTB(Reg m, Reg d) {
const auto byte = ir.LeastSignificantByte(ir.GetRegister(m)); const auto byte = ir.LeastSignificantByte(ir.GetRegister(m));
ir.SetRegister(d, ir.SignExtendByteToWord(byte)); ir.SetRegister(d, ir.SignExtendByteToWord(byte));
return true; return true;
@ -775,7 +775,7 @@ bool ThumbTranslatorVisitor::thumb16_SXTB(Reg m, Reg d) {
// UXTH <Rd>, <Rm> // UXTH <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_UXTH(Reg m, Reg d) { bool TranslatorVisitor::thumb16_UXTH(Reg m, Reg d) {
const auto half = ir.LeastSignificantHalf(ir.GetRegister(m)); const auto half = ir.LeastSignificantHalf(ir.GetRegister(m));
ir.SetRegister(d, ir.ZeroExtendHalfToWord(half)); ir.SetRegister(d, ir.ZeroExtendHalfToWord(half));
return true; return true;
@ -783,7 +783,7 @@ bool ThumbTranslatorVisitor::thumb16_UXTH(Reg m, Reg d) {
// UXTB <Rd>, <Rm> // UXTB <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_UXTB(Reg m, Reg d) { bool TranslatorVisitor::thumb16_UXTB(Reg m, Reg d) {
const auto byte = ir.LeastSignificantByte(ir.GetRegister(m)); const auto byte = ir.LeastSignificantByte(ir.GetRegister(m));
ir.SetRegister(d, ir.ZeroExtendByteToWord(byte)); ir.SetRegister(d, ir.ZeroExtendByteToWord(byte));
return true; return true;
@ -791,7 +791,7 @@ bool ThumbTranslatorVisitor::thumb16_UXTB(Reg m, Reg d) {
// PUSH <reg_list> // PUSH <reg_list>
// reg_list cannot encode for R15. // reg_list cannot encode for R15.
bool ThumbTranslatorVisitor::thumb16_PUSH(bool M, RegList reg_list) { bool TranslatorVisitor::thumb16_PUSH(bool M, RegList reg_list) {
if (M) { if (M) {
reg_list |= 1 << 14; reg_list |= 1 << 14;
} }
@ -817,7 +817,7 @@ bool ThumbTranslatorVisitor::thumb16_PUSH(bool M, RegList reg_list) {
} }
// POP <reg_list> // POP <reg_list>
bool ThumbTranslatorVisitor::thumb16_POP(bool P, RegList reg_list) { bool TranslatorVisitor::thumb16_POP(bool P, RegList reg_list) {
if (P) { if (P) {
reg_list |= 1 << 15; reg_list |= 1 << 15;
} }
@ -851,7 +851,7 @@ bool ThumbTranslatorVisitor::thumb16_POP(bool P, RegList reg_list) {
} }
// SETEND <endianness> // SETEND <endianness>
bool ThumbTranslatorVisitor::thumb16_SETEND(bool E) { bool TranslatorVisitor::thumb16_SETEND(bool E) {
if (ir.current_location.IT().IsInITBlock()) { if (ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -866,13 +866,13 @@ bool ThumbTranslatorVisitor::thumb16_SETEND(bool E) {
// CPS{IE,ID} <a,i,f> // CPS{IE,ID} <a,i,f>
// A CPS is treated as a NOP in User mode. // A CPS is treated as a NOP in User mode.
bool ThumbTranslatorVisitor::thumb16_CPS(bool, bool, bool, bool) { bool TranslatorVisitor::thumb16_CPS(bool, bool, bool, bool) {
return true; return true;
} }
// REV <Rd>, <Rm> // REV <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_REV(Reg m, Reg d) { bool TranslatorVisitor::thumb16_REV(Reg m, Reg d) {
ir.SetRegister(d, ir.ByteReverseWord(ir.GetRegister(m))); ir.SetRegister(d, ir.ByteReverseWord(ir.GetRegister(m)));
return true; return true;
} }
@ -880,7 +880,7 @@ bool ThumbTranslatorVisitor::thumb16_REV(Reg m, Reg d) {
// REV16 <Rd>, <Rm> // REV16 <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
// TODO: Consider optimizing // TODO: Consider optimizing
bool ThumbTranslatorVisitor::thumb16_REV16(Reg m, Reg d) { bool TranslatorVisitor::thumb16_REV16(Reg m, Reg d) {
const auto Rm = ir.GetRegister(m); const auto Rm = ir.GetRegister(m);
const auto upper_half = ir.LeastSignificantHalf(ir.LogicalShiftRight(Rm, ir.Imm8(16), ir.Imm1(0)).result); const auto upper_half = ir.LeastSignificantHalf(ir.LogicalShiftRight(Rm, ir.Imm8(16), ir.Imm1(0)).result);
const auto lower_half = ir.LeastSignificantHalf(Rm); const auto lower_half = ir.LeastSignificantHalf(Rm);
@ -895,14 +895,14 @@ bool ThumbTranslatorVisitor::thumb16_REV16(Reg m, Reg d) {
// REVSH <Rd>, <Rm> // REVSH <Rd>, <Rm>
// Rd cannot encode R15. // Rd cannot encode R15.
bool ThumbTranslatorVisitor::thumb16_REVSH(Reg m, Reg d) { bool TranslatorVisitor::thumb16_REVSH(Reg m, Reg d) {
const auto rev_half = ir.ByteReverseHalf(ir.LeastSignificantHalf(ir.GetRegister(m))); const auto rev_half = ir.ByteReverseHalf(ir.LeastSignificantHalf(ir.GetRegister(m)));
ir.SetRegister(d, ir.SignExtendHalfToWord(rev_half)); ir.SetRegister(d, ir.SignExtendHalfToWord(rev_half));
return true; return true;
} }
// BKPT #<imm8> // BKPT #<imm8>
bool ThumbTranslatorVisitor::thumb16_BKPT([[maybe_unused]] Imm<8> imm8) { bool TranslatorVisitor::thumb16_BKPT(Imm<8> /*imm8*/) {
ir.ExceptionRaised(Exception::Breakpoint); ir.ExceptionRaised(Exception::Breakpoint);
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
ir.LoadWritePC(ir.Imm32(ir.current_location.PC())); ir.LoadWritePC(ir.Imm32(ir.current_location.PC()));
@ -911,7 +911,7 @@ bool ThumbTranslatorVisitor::thumb16_BKPT([[maybe_unused]] Imm<8> imm8) {
} }
// STM <Rn>!, <reg_list> // STM <Rn>!, <reg_list>
bool ThumbTranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) { bool TranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
if (Common::BitCount(reg_list) == 0) { if (Common::BitCount(reg_list) == 0) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -933,7 +933,7 @@ bool ThumbTranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
} }
// LDM <Rn>!, <reg_list> // LDM <Rn>!, <reg_list>
bool ThumbTranslatorVisitor::thumb16_LDMIA(Reg n, RegList reg_list) { bool TranslatorVisitor::thumb16_LDMIA(Reg n, RegList reg_list) {
if (Common::BitCount(reg_list) == 0) { if (Common::BitCount(reg_list) == 0) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -956,7 +956,7 @@ bool ThumbTranslatorVisitor::thumb16_LDMIA(Reg n, RegList reg_list) {
} }
// CB{N}Z <Rn>, <label> // CB{N}Z <Rn>, <label>
bool ThumbTranslatorVisitor::thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm5, Reg n) { bool TranslatorVisitor::thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm5, Reg n) {
if (ir.current_location.IT().IsInITBlock()) { if (ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -981,12 +981,12 @@ bool ThumbTranslatorVisitor::thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm
return false; return false;
} }
bool ThumbTranslatorVisitor::thumb16_UDF() { bool TranslatorVisitor::thumb16_UDF() {
return UndefinedInstruction(); return UndefinedInstruction();
} }
// BX <Rm> // BX <Rm>
bool ThumbTranslatorVisitor::thumb16_BX(Reg m) { bool TranslatorVisitor::thumb16_BX(Reg m) {
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) { if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -1001,7 +1001,7 @@ bool ThumbTranslatorVisitor::thumb16_BX(Reg m) {
} }
// BLX <Rm> // BLX <Rm>
bool ThumbTranslatorVisitor::thumb16_BLX_reg(Reg m) { bool TranslatorVisitor::thumb16_BLX_reg(Reg m) {
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) { if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -1015,7 +1015,7 @@ bool ThumbTranslatorVisitor::thumb16_BLX_reg(Reg m) {
} }
// SVC #<imm8> // SVC #<imm8>
bool ThumbTranslatorVisitor::thumb16_SVC(Imm<8> imm8) { bool TranslatorVisitor::thumb16_SVC(Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend(); const u32 imm32 = imm8.ZeroExtend();
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2)); ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2));
@ -1026,7 +1026,7 @@ bool ThumbTranslatorVisitor::thumb16_SVC(Imm<8> imm8) {
} }
// B<cond> <label> // B<cond> <label>
bool ThumbTranslatorVisitor::thumb16_B_t1(Cond cond, Imm<8> imm8) { bool TranslatorVisitor::thumb16_B_t1(Cond cond, Imm<8> imm8) {
if (ir.current_location.IT().IsInITBlock()) { if (ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -1044,7 +1044,7 @@ bool ThumbTranslatorVisitor::thumb16_B_t1(Cond cond, Imm<8> imm8) {
} }
// B <label> // B <label>
bool ThumbTranslatorVisitor::thumb16_B_t2(Imm<11> imm11) { bool TranslatorVisitor::thumb16_B_t2(Imm<11> imm11) {
if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) { if (ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,12 +3,12 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// BL <label> // BL <label>
bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) { bool TranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
const Imm<1> i1{j1 == S}; const Imm<1> i1{j1 == S};
const Imm<1> i2{j2 == S}; const Imm<1> i2{j2 == S};
@ -28,7 +28,7 @@ bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm
} }
// BLX <label> // BLX <label>
bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) { bool TranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
const Imm<1> i1{j1 == S}; const Imm<1> i1{j1 == S};
const Imm<1> i2{j2 == S}; const Imm<1> i2{j2 == S};
@ -52,7 +52,7 @@ bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Im
return false; return false;
} }
bool ThumbTranslatorVisitor::thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) { bool TranslatorVisitor::thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo) {
const Imm<1> i1{j1 == S}; const Imm<1> i1{j1 == S};
const Imm<1> i2{j2 == S}; const Imm<1> i2{j2 == S};
@ -68,7 +68,7 @@ bool ThumbTranslatorVisitor::thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j
return false; return false;
} }
bool ThumbTranslatorVisitor::thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> i1, Imm<1> i2, Imm<11> lo) { bool TranslatorVisitor::thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> i1, Imm<1> i2, Imm<11> lo) {
if (ir.current_location.IT().IsInITBlock()) { if (ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ThumbTranslatorVisitor::thumb32_BXJ(Reg m) { bool TranslatorVisitor::thumb32_BXJ(Reg m) {
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -15,22 +15,22 @@ bool ThumbTranslatorVisitor::thumb32_BXJ(Reg m) {
return thumb16_BX(m); return thumb16_BX(m);
} }
bool ThumbTranslatorVisitor::thumb32_CLREX() { bool TranslatorVisitor::thumb32_CLREX() {
ir.ClearExclusive(); ir.ClearExclusive();
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_DMB([[maybe_unused]] Imm<4> option) { bool TranslatorVisitor::thumb32_DMB(Imm<4> /*option*/) {
ir.DataMemoryBarrier(); ir.DataMemoryBarrier();
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_DSB([[maybe_unused]] Imm<4> option) { bool TranslatorVisitor::thumb32_DSB(Imm<4> /*option*/) {
ir.DataSynchronizationBarrier(); ir.DataSynchronizationBarrier();
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ISB([[maybe_unused]] Imm<4> option) { bool TranslatorVisitor::thumb32_ISB(Imm<4> /*option*/) {
ir.InstructionSynchronizationBarrier(); ir.InstructionSynchronizationBarrier();
ir.UpdateUpperLocationDescriptor(); ir.UpdateUpperLocationDescriptor();
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4)); ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
@ -38,31 +38,31 @@ bool ThumbTranslatorVisitor::thumb32_ISB([[maybe_unused]] Imm<4> option) {
return false; return false;
} }
bool ThumbTranslatorVisitor::thumb32_NOP() { bool TranslatorVisitor::thumb32_NOP() {
return thumb16_NOP(); return thumb16_NOP();
} }
bool ThumbTranslatorVisitor::thumb32_SEV() { bool TranslatorVisitor::thumb32_SEV() {
return thumb16_SEV(); return thumb16_SEV();
} }
bool ThumbTranslatorVisitor::thumb32_SEVL() { bool TranslatorVisitor::thumb32_SEVL() {
return thumb16_SEVL(); return thumb16_SEVL();
} }
bool ThumbTranslatorVisitor::thumb32_UDF() { bool TranslatorVisitor::thumb32_UDF() {
return thumb16_UDF(); return thumb16_UDF();
} }
bool ThumbTranslatorVisitor::thumb32_WFE() { bool TranslatorVisitor::thumb32_WFE() {
return thumb16_WFE(); return thumb16_WFE();
} }
bool ThumbTranslatorVisitor::thumb32_WFI() { bool TranslatorVisitor::thumb32_WFI() {
return thumb16_WFI(); return thumb16_WFI();
} }
bool ThumbTranslatorVisitor::thumb32_YIELD() { bool TranslatorVisitor::thumb32_YIELD() {
return thumb16_YIELD(); return thumb16_YIELD();
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ThumbTranslatorVisitor::thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) { bool TranslatorVisitor::thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -21,7 +21,7 @@ bool ThumbTranslatorVisitor::thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -39,7 +39,7 @@ bool ThumbTranslatorVisitor::thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_BIC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_BIC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -56,7 +56,7 @@ bool ThumbTranslatorVisitor::thumb32_BIC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -73,7 +73,7 @@ bool ThumbTranslatorVisitor::thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(n != Reg::PC, "Decode error"); ASSERT_MSG(n != Reg::PC, "Decode error");
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -91,7 +91,7 @@ bool ThumbTranslatorVisitor::thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -108,7 +108,7 @@ bool ThumbTranslatorVisitor::thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(n != Reg::PC, "Decode error"); ASSERT_MSG(n != Reg::PC, "Decode error");
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -126,7 +126,7 @@ bool ThumbTranslatorVisitor::thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) { bool TranslatorVisitor::thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -140,7 +140,7 @@ bool ThumbTranslatorVisitor::thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -158,7 +158,7 @@ bool ThumbTranslatorVisitor::thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) { bool TranslatorVisitor::thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -173,7 +173,7 @@ bool ThumbTranslatorVisitor::thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -192,7 +192,7 @@ bool ThumbTranslatorVisitor::thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> i
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -210,7 +210,7 @@ bool ThumbTranslatorVisitor::thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -228,7 +228,7 @@ bool ThumbTranslatorVisitor::thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) { bool TranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -243,7 +243,7 @@ bool ThumbTranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -262,7 +262,7 @@ bool ThumbTranslatorVisitor::thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> i
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_RSB_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_RSB_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,9 +3,10 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) { static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) {
@ -18,7 +19,7 @@ static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
using SaturationFunction = IR::ResultAndOverflow<IR::U32> (IREmitter::*)(const IR::U32&, size_t); using SaturationFunction = IR::ResultAndOverflow<IR::U32> (IREmitter::*)(const IR::U32&, size_t);
static bool Saturation(ThumbTranslatorVisitor& v, bool sh, Reg n, Reg d, Imm<5> shift_amount, size_t saturate_to, SaturationFunction sat_fn) { static bool Saturation(TranslatorVisitor& v, bool sh, Reg n, Reg d, Imm<5> shift_amount, size_t saturate_to, SaturationFunction sat_fn) {
ASSERT_MSG(!(sh && shift_amount == 0), "Invalid decode"); ASSERT_MSG(!(sh && shift_amount == 0), "Invalid decode");
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
@ -34,7 +35,7 @@ static bool Saturation(ThumbTranslatorVisitor& v, bool sh, Reg n, Reg d, Imm<5>
return true; return true;
} }
static bool Saturation16(ThumbTranslatorVisitor& v, Reg n, Reg d, size_t saturate_to, SaturationFunction sat_fn) { static bool Saturation16(TranslatorVisitor& v, Reg n, Reg d, size_t saturate_to, SaturationFunction sat_fn) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -52,7 +53,7 @@ static bool Saturation16(ThumbTranslatorVisitor& v, Reg n, Reg d, size_t saturat
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADR_t2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ADR_t2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -64,7 +65,7 @@ bool ThumbTranslatorVisitor::thumb32_ADR_t2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADR_t3(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ADR_t3(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -76,7 +77,7 @@ bool ThumbTranslatorVisitor::thumb32_ADR_t3(Imm<1> imm1, Imm<3> imm3, Reg d, Imm
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADD_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_ADD_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -89,7 +90,7 @@ bool ThumbTranslatorVisitor::thumb32_ADD_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_BFC(Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb) { bool TranslatorVisitor::thumb32_BFC(Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -109,7 +110,7 @@ bool ThumbTranslatorVisitor::thumb32_BFC(Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5>
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb) { bool TranslatorVisitor::thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -131,7 +132,7 @@ bool ThumbTranslatorVisitor::thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -144,7 +145,7 @@ bool ThumbTranslatorVisitor::thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -155,7 +156,7 @@ bool ThumbTranslatorVisitor::thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> i
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1) { bool TranslatorVisitor::thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -179,15 +180,15 @@ bool ThumbTranslatorVisitor::thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SSAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm) { bool TranslatorVisitor::thumb32_SSAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm) {
return Saturation(*this, sh, n, d, concatenate(imm3, imm2), sat_imm.ZeroExtend() + 1, &IREmitter::SignedSaturation); return Saturation(*this, sh, n, d, concatenate(imm3, imm2), sat_imm.ZeroExtend() + 1, &IREmitter::SignedSaturation);
} }
bool ThumbTranslatorVisitor::thumb32_SSAT16(Reg n, Reg d, Imm<4> sat_imm) { bool TranslatorVisitor::thumb32_SSAT16(Reg n, Reg d, Imm<4> sat_imm) {
return Saturation16(*this, n, d, sat_imm.ZeroExtend() + 1, &IREmitter::SignedSaturation); return Saturation16(*this, n, d, sat_imm.ZeroExtend() + 1, &IREmitter::SignedSaturation);
} }
bool ThumbTranslatorVisitor::thumb32_SUB_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_SUB_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8) {
if (d == Reg::PC) { if (d == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -200,7 +201,7 @@ bool ThumbTranslatorVisitor::thumb32_SUB_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1) { bool TranslatorVisitor::thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1) {
if (d == Reg::PC || n == Reg::PC) { if (d == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -220,11 +221,11 @@ bool ThumbTranslatorVisitor::thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_USAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm) { bool TranslatorVisitor::thumb32_USAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm) {
return Saturation(*this, sh, n, d, concatenate(imm3, imm2), sat_imm.ZeroExtend(), &IREmitter::UnsignedSaturation); return Saturation(*this, sh, n, d, concatenate(imm3, imm2), sat_imm.ZeroExtend(), &IREmitter::UnsignedSaturation);
} }
bool ThumbTranslatorVisitor::thumb32_USAT16(Reg n, Reg d, Imm<4> sat_imm) { bool TranslatorVisitor::thumb32_USAT16(Reg n, Reg d, Imm<4> sat_imm) {
return Saturation16(*this, n, d, sat_imm.ZeroExtend(), &IREmitter::UnsignedSaturation); return Saturation16(*this, n, d, sat_imm.ZeroExtend(), &IREmitter::UnsignedSaturation);
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
@ -14,7 +14,7 @@ IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
using ShiftFunction = IR::ResultAndCarry<IR::U32> (IREmitter::*)(const IR::U32&, const IR::U8&, const IR::U1&); using ShiftFunction = IR::ResultAndCarry<IR::U32> (IREmitter::*)(const IR::U32&, const IR::U8&, const IR::U1&);
bool ShiftInstruction(ThumbTranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunction shift_fn) { bool ShiftInstruction(TranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunction shift_fn) {
if (d == Reg::PC || m == Reg::PC || s == Reg::PC) { if (d == Reg::PC || m == Reg::PC || s == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -28,23 +28,23 @@ bool ShiftInstruction(ThumbTranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunct
} }
} // Anonymous namespace } // Anonymous namespace
bool ThumbTranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) { bool TranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::ArithmeticShiftRight); return ShiftInstruction(*this, m, d, s, &IREmitter::ArithmeticShiftRight);
} }
bool ThumbTranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) { bool TranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftLeft); return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftLeft);
} }
bool ThumbTranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) { bool TranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftRight); return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftRight);
} }
bool ThumbTranslatorVisitor::thumb32_ROR_reg(Reg m, Reg d, Reg s) { bool TranslatorVisitor::thumb32_ROR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::RotateRight); return ShiftInstruction(*this, m, d, s, &IREmitter::RotateRight);
} }
bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -56,7 +56,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -70,7 +70,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTB16(Reg d, SignExtendRotation rotate, Re
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -83,7 +83,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rota
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_SXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -98,7 +98,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTAB16(Reg n, Reg d, SignExtendRotation ro
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SXTH(Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_SXTH(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -110,7 +110,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTH(Reg d, SignExtendRotation rotate, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_SXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -123,7 +123,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTAH(Reg n, Reg d, SignExtendRotation rota
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UXTB(Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_UXTB(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -135,7 +135,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTB(Reg d, SignExtendRotation rotate, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UXTB16(Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_UXTB16(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -147,7 +147,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTB16(Reg d, SignExtendRotation rotate, Re
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_UXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -160,7 +160,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTAB(Reg n, Reg d, SignExtendRotation rota
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_UXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -174,7 +174,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTAB16(Reg n, Reg d, SignExtendRotation ro
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UXTH(Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_UXTH(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -186,7 +186,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTH(Reg d, SignExtendRotation rotate, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m) { bool TranslatorVisitor::thumb32_UXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ThumbTranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) {
if (n == Reg::PC || m == Reg::PC) { if (n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -21,7 +21,7 @@ bool ThumbTranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
@ -39,7 +39,7 @@ bool ThumbTranslatorVisitor::thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_BIC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_BIC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -55,7 +55,7 @@ bool ThumbTranslatorVisitor::thumb32_BIC_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -71,7 +71,7 @@ bool ThumbTranslatorVisitor::thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2>
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(n != Reg::PC, "Decode error"); ASSERT_MSG(n != Reg::PC, "Decode error");
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
@ -89,7 +89,7 @@ bool ThumbTranslatorVisitor::thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -105,7 +105,7 @@ bool ThumbTranslatorVisitor::thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2>
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(n != Reg::PC, "Decode error"); ASSERT_MSG(n != Reg::PC, "Decode error");
if (d == Reg::PC || m == Reg::PC) { if (d == Reg::PC || m == Reg::PC) {
@ -123,7 +123,7 @@ bool ThumbTranslatorVisitor::thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) {
if (n == Reg::PC || m == Reg::PC) { if (n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -137,7 +137,7 @@ bool ThumbTranslatorVisitor::thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
@ -155,7 +155,7 @@ bool ThumbTranslatorVisitor::thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_PKH(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<1> tb, Reg m) { bool TranslatorVisitor::thumb32_PKH(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<1> tb, Reg m) {
const ShiftType type = concatenate(tb, Imm<1>{0}).ZeroExtend<ShiftType>(); const ShiftType type = concatenate(tb, Imm<1>{0}).ZeroExtend<ShiftType>();
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
@ -170,7 +170,7 @@ bool ThumbTranslatorVisitor::thumb32_PKH(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) {
if (n == Reg::PC || m == Reg::PC) { if (n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -185,7 +185,7 @@ bool ThumbTranslatorVisitor::thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
@ -204,7 +204,7 @@ bool ThumbTranslatorVisitor::thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_ADC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_ADC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -221,7 +221,7 @@ bool ThumbTranslatorVisitor::thumb32_ADC_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -238,7 +238,7 @@ bool ThumbTranslatorVisitor::thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) {
if (n == Reg::PC || m == Reg::PC) { if (n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -253,7 +253,7 @@ bool ThumbTranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error"); ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) { if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
@ -272,7 +272,7 @@ bool ThumbTranslatorVisitor::thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_RSB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) { bool TranslatorVisitor::thumb32_RSB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,11 +3,12 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include <dynarmic/A32/config.h> #include <dynarmic/A32/config.h>
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static bool PLDHandler(ThumbTranslatorVisitor& v, bool W) { static bool PLDHandler(TranslatorVisitor& v, bool W) {
if (!v.options.hook_hint_instructions) { if (!v.options.hook_hint_instructions) {
return true; return true;
} }
@ -17,7 +18,7 @@ static bool PLDHandler(ThumbTranslatorVisitor& v, bool W) {
return v.RaiseException(exception); return v.RaiseException(exception);
} }
static bool PLIHandler(ThumbTranslatorVisitor& v) { static bool PLIHandler(TranslatorVisitor& v) {
if (!v.options.hook_hint_instructions) { if (!v.options.hook_hint_instructions) {
return true; return true;
} }
@ -27,7 +28,7 @@ static bool PLIHandler(ThumbTranslatorVisitor& v) {
using ExtensionFunction = IR::U32 (IREmitter::*)(const IR::U8&); using ExtensionFunction = IR::U32 (IREmitter::*)(const IR::U8&);
static bool LoadByteLiteral(ThumbTranslatorVisitor& v, bool U, Reg t, Imm<12> imm12, static bool LoadByteLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12,
ExtensionFunction ext_fn) { ExtensionFunction ext_fn) {
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const u32 base = v.ir.AlignPC(4); const u32 base = v.ir.AlignPC(4);
@ -38,7 +39,7 @@ static bool LoadByteLiteral(ThumbTranslatorVisitor& v, bool U, Reg t, Imm<12> im
return true; return true;
} }
static bool LoadByteRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, static bool LoadByteRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m,
ExtensionFunction ext_fn) { ExtensionFunction ext_fn) {
if (m == Reg::PC) { if (m == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
@ -54,8 +55,8 @@ static bool LoadByteRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm
return true; return true;
} }
static bool LoadByteImmediate(ThumbTranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, static bool LoadByteImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12,
Imm<12> imm12, ExtensionFunction ext_fn) { ExtensionFunction ext_fn) {
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const IR::U32 reg_n = v.ir.GetRegister(n); const IR::U32 reg_n = v.ir.GetRegister(n);
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm32)) const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm32))
@ -70,27 +71,19 @@ static bool LoadByteImmediate(ThumbTranslatorVisitor& v, Reg n, Reg t, bool P, b
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_PLD_lit([[maybe_unused]] bool U, bool TranslatorVisitor::thumb32_PLD_lit(bool /*U*/, Imm<12> /*imm12*/) {
[[maybe_unused]] Imm<12> imm12) {
return PLDHandler(*this, false); return PLDHandler(*this, false);
} }
bool ThumbTranslatorVisitor::thumb32_PLD_imm8(bool W, bool TranslatorVisitor::thumb32_PLD_imm8(bool W, Reg /*n*/, Imm<8> /*imm8*/) {
[[maybe_unused]] Reg n,
[[maybe_unused]] Imm<8> imm8) {
return PLDHandler(*this, W); return PLDHandler(*this, W);
} }
bool ThumbTranslatorVisitor::thumb32_PLD_imm12(bool W, bool TranslatorVisitor::thumb32_PLD_imm12(bool W, Reg /*n*/, Imm<12> /*imm12*/) {
[[maybe_unused]] Reg n,
[[maybe_unused]] Imm<12> imm12) {
return PLDHandler(*this, W); return PLDHandler(*this, W);
} }
bool ThumbTranslatorVisitor::thumb32_PLD_reg(bool W, bool TranslatorVisitor::thumb32_PLD_reg(bool W, Reg /*n*/, Imm<2> /*imm2*/, Reg m) {
[[maybe_unused]] Reg n,
[[maybe_unused]] Imm<2> imm2,
Reg m) {
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -98,24 +91,19 @@ bool ThumbTranslatorVisitor::thumb32_PLD_reg(bool W,
return PLDHandler(*this, W); return PLDHandler(*this, W);
} }
bool ThumbTranslatorVisitor::thumb32_PLI_lit([[maybe_unused]] bool U, bool TranslatorVisitor::thumb32_PLI_lit(bool /*U*/, Imm<12> /*imm12*/) {
[[maybe_unused]] Imm<12> imm12) {
return PLIHandler(*this); return PLIHandler(*this);
} }
bool ThumbTranslatorVisitor::thumb32_PLI_imm8([[maybe_unused]] Reg n, bool TranslatorVisitor::thumb32_PLI_imm8(Reg /*n*/, Imm<8> /*imm8*/) {
[[maybe_unused]] Imm<8> imm8) {
return PLIHandler(*this); return PLIHandler(*this);
} }
bool ThumbTranslatorVisitor::thumb32_PLI_imm12([[maybe_unused]] Reg n, bool TranslatorVisitor::thumb32_PLI_imm12(Reg /*n*/, Imm<12> /*imm12*/) {
[[maybe_unused]] Imm<12> imm12) {
return PLIHandler(*this); return PLIHandler(*this);
} }
bool ThumbTranslatorVisitor::thumb32_PLI_reg([[maybe_unused]] Reg n, bool TranslatorVisitor::thumb32_PLI_reg(Reg /*n*/, Imm<2> /*imm2*/, Reg m) {
[[maybe_unused]] Imm<2> imm2,
Reg m) {
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -123,11 +111,12 @@ bool ThumbTranslatorVisitor::thumb32_PLI_reg([[maybe_unused]] Reg n,
return PLIHandler(*this); return PLIHandler(*this);
} }
bool ThumbTranslatorVisitor::thumb32_LDRB_lit(bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRB_lit(bool U, Reg t, Imm<12> imm12) {
return LoadByteLiteral(*this, U, t, imm12, &IREmitter::ZeroExtendByteToWord); return LoadByteLiteral(*this, U, t, imm12,
&IREmitter::ZeroExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) {
if (t == Reg::PC && W) { if (t == Reg::PC && W) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -142,16 +131,17 @@ bool ThumbTranslatorVisitor::thumb32_LDRB_imm8(Reg n, Reg t, bool P, bool U, boo
&IREmitter::ZeroExtendByteToWord); &IREmitter::ZeroExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRB_imm12(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRB_imm12(Reg n, Reg t, Imm<12> imm12) {
return LoadByteImmediate(*this, n, t, true, true, false, imm12, return LoadByteImmediate(*this, n, t, true, true, false, imm12,
&IREmitter::ZeroExtendByteToWord); &IREmitter::ZeroExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRB_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_LDRB_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return LoadByteRegister(*this, n, t, imm2, m, &IREmitter::ZeroExtendByteToWord); return LoadByteRegister(*this, n, t, imm2, m,
&IREmitter::ZeroExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRBT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRBT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution modes. // privileged execution modes.
@ -165,11 +155,12 @@ bool ThumbTranslatorVisitor::thumb32_LDRBT(Reg n, Reg t, Imm<8> imm8) {
return thumb32_LDRB_imm8(n, t, true, true, false, imm8); return thumb32_LDRB_imm8(n, t, true, true, false, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSB_lit(bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRSB_lit(bool U, Reg t, Imm<12> imm12) {
return LoadByteLiteral(*this, U, t, imm12, &IREmitter::SignExtendByteToWord); return LoadByteLiteral(*this, U, t, imm12,
&IREmitter::SignExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRSB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) {
if (t == Reg::PC && W) { if (t == Reg::PC && W) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -184,16 +175,17 @@ bool ThumbTranslatorVisitor::thumb32_LDRSB_imm8(Reg n, Reg t, bool P, bool U, bo
&IREmitter::SignExtendByteToWord); &IREmitter::SignExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSB_imm12(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRSB_imm12(Reg n, Reg t, Imm<12> imm12) {
return LoadByteImmediate(*this, n, t, true, true, false, imm12, return LoadByteImmediate(*this, n, t, true, true, false, imm12,
&IREmitter::SignExtendByteToWord); &IREmitter::SignExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSB_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_LDRSB_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return LoadByteRegister(*this, n, t, imm2, m, &IREmitter::SignExtendByteToWord); return LoadByteRegister(*this, n, t, imm2, m,
&IREmitter::SignExtendByteToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSBT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRSBT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution modes. // privileged execution modes.

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
using ExtensionFunction = IR::U32 (IREmitter::*)(const IR::U16&); using ExtensionFunction = IR::U32 (IREmitter::*)(const IR::U16&);
static bool LoadHalfLiteral(ThumbTranslatorVisitor& v, bool U, Reg t, Imm<12> imm12, static bool LoadHalfLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12,
ExtensionFunction ext_fn) { ExtensionFunction ext_fn) {
const auto imm32 = imm12.ZeroExtend(); const auto imm32 = imm12.ZeroExtend();
const auto base = v.ir.AlignPC(4); const auto base = v.ir.AlignPC(4);
@ -20,7 +20,7 @@ static bool LoadHalfLiteral(ThumbTranslatorVisitor& v, bool U, Reg t, Imm<12> im
return true; return true;
} }
static bool LoadHalfRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, static bool LoadHalfRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m,
ExtensionFunction ext_fn) { ExtensionFunction ext_fn) {
if (m == Reg::PC) { if (m == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
@ -36,7 +36,7 @@ static bool LoadHalfRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm
return true; return true;
} }
static bool LoadHalfImmediate(ThumbTranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, static bool LoadHalfImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W,
Imm<12> imm12, ExtensionFunction ext_fn) { Imm<12> imm12, ExtensionFunction ext_fn) {
const u32 imm32 = imm12.ZeroExtend(); const u32 imm32 = imm12.ZeroExtend();
const IR::U32 reg_n = v.ir.GetRegister(n); const IR::U32 reg_n = v.ir.GetRegister(n);
@ -54,15 +54,15 @@ static bool LoadHalfImmediate(ThumbTranslatorVisitor& v, Reg n, Reg t, bool P, b
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDRH_lit(bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRH_lit(bool U, Reg t, Imm<12> imm12) {
return LoadHalfLiteral(*this, U, t, imm12, &IREmitter::ZeroExtendHalfToWord); return LoadHalfLiteral(*this, U, t, imm12, &IREmitter::ZeroExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRH_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_LDRH_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return LoadHalfRegister(*this, n, t, imm2, m, &IREmitter::ZeroExtendHalfToWord); return LoadHalfRegister(*this, n, t, imm2, m, &IREmitter::ZeroExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) {
if (!P && !W) { if (!P && !W) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -77,12 +77,12 @@ bool ThumbTranslatorVisitor::thumb32_LDRH_imm8(Reg n, Reg t, bool P, bool U, boo
&IREmitter::ZeroExtendHalfToWord); &IREmitter::ZeroExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRH_imm12(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRH_imm12(Reg n, Reg t, Imm<12> imm12) {
return LoadHalfImmediate(*this, n, t, true, true, false, imm12, return LoadHalfImmediate(*this, n, t, true, true, false, imm12,
&IREmitter::ZeroExtendHalfToWord); &IREmitter::ZeroExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRHT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRHT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution levels. // privileged execution levels.
@ -96,15 +96,15 @@ bool ThumbTranslatorVisitor::thumb32_LDRHT(Reg n, Reg t, Imm<8> imm8) {
return thumb32_LDRH_imm8(n, t, true, true, false, imm8); return thumb32_LDRH_imm8(n, t, true, true, false, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSH_lit(bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRSH_lit(bool U, Reg t, Imm<12> imm12) {
return LoadHalfLiteral(*this, U, t, imm12, &IREmitter::SignExtendHalfToWord); return LoadHalfLiteral(*this, U, t, imm12, &IREmitter::SignExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSH_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_LDRSH_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return LoadHalfRegister(*this, n, t, imm2, m, &IREmitter::SignExtendHalfToWord); return LoadHalfRegister(*this, n, t, imm2, m, &IREmitter::SignExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRSH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) {
if (!P && !W) { if (!P && !W) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -119,12 +119,12 @@ bool ThumbTranslatorVisitor::thumb32_LDRSH_imm8(Reg n, Reg t, bool P, bool U, bo
&IREmitter::SignExtendHalfToWord); &IREmitter::SignExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSH_imm12(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDRSH_imm12(Reg n, Reg t, Imm<12> imm12) {
return LoadHalfImmediate(*this, n, t, true, true, false, imm12, return LoadHalfImmediate(*this, n, t, true, true, false, imm12,
&IREmitter::SignExtendHalfToWord); &IREmitter::SignExtendHalfToWord);
} }
bool ThumbTranslatorVisitor::thumb32_LDRSHT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRSHT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution levels. // privileged execution levels.

View file

@ -3,15 +3,16 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static bool ITBlockCheck(const A32::IREmitter& ir) { static bool ITBlockCheck(const A32::IREmitter& ir) {
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock(); return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
} }
static bool TableBranch(ThumbTranslatorVisitor& v, Reg n, Reg m, bool half) { static bool TableBranch(TranslatorVisitor& v, Reg n, Reg m, bool half) {
if (m == Reg::PC) { if (m == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -39,7 +40,7 @@ static bool TableBranch(ThumbTranslatorVisitor& v, Reg n, Reg m, bool half) {
return false; return false;
} }
static bool LoadDualImmediate(ThumbTranslatorVisitor& v, bool P, bool U, bool W, static bool LoadDualImmediate(TranslatorVisitor& v, bool P, bool U, bool W,
Reg n, Reg t, Reg t2, Imm<8> imm8) { Reg n, Reg t, Reg t2, Imm<8> imm8) {
if (W && (n == t || n == t2)) { if (W && (n == t || n == t2)) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
@ -65,7 +66,7 @@ static bool LoadDualImmediate(ThumbTranslatorVisitor& v, bool P, bool U, bool W,
return true; return true;
} }
static bool LoadDualLiteral(ThumbTranslatorVisitor& v, bool U, bool W, Reg t, Reg t2, Imm<8> imm8) { static bool LoadDualLiteral(TranslatorVisitor& v, bool U, bool W, Reg t, Reg t2, Imm<8> imm8) {
if (t == Reg::PC || t2 == Reg::PC || t == t2) { if (t == Reg::PC || t2 == Reg::PC || t == t2) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -83,7 +84,7 @@ static bool LoadDualLiteral(ThumbTranslatorVisitor& v, bool U, bool W, Reg t, Re
return true; return true;
} }
static bool StoreDual(ThumbTranslatorVisitor& v, bool P, bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) { static bool StoreDual(TranslatorVisitor& v, bool P, bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) {
if (W && (n == t || n == t2)) { if (W && (n == t || n == t2)) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -111,31 +112,31 @@ static bool StoreDual(ThumbTranslatorVisitor& v, bool P, bool U, bool W, Reg n,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualImmediate(*this, false, U, true, n, t, t2, imm8); return LoadDualImmediate(*this, false, U, true, n, t, t2, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualImmediate(*this, true, U, W, n, t, t2, imm8); return LoadDualImmediate(*this, true, U, W, n, t, t2, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualLiteral(*this, U, true, t, t2, imm8); return LoadDualLiteral(*this, U, true, t, t2, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualLiteral(*this, U, W, t, t2, imm8); return LoadDualLiteral(*this, U, W, t, t2, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) {
return StoreDual(*this, false, U, true, n, t, t2, imm8); return StoreDual(*this, false, U, true, n, t, t2, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) {
return StoreDual(*this, true, U, W, n, t, t2, imm8); return StoreDual(*this, true, U, W, n, t, t2, imm8);
} }
bool ThumbTranslatorVisitor::thumb32_LDREX(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDREX(Reg n, Reg t, Imm<8> imm8) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -147,7 +148,7 @@ bool ThumbTranslatorVisitor::thumb32_LDREX(Reg n, Reg t, Imm<8> imm8) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDREXB(Reg n, Reg t) { bool TranslatorVisitor::thumb32_LDREXB(Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -159,7 +160,7 @@ bool ThumbTranslatorVisitor::thumb32_LDREXB(Reg n, Reg t) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDREXD(Reg n, Reg t, Reg t2) { bool TranslatorVisitor::thumb32_LDREXD(Reg n, Reg t, Reg t2) {
if (t == Reg::PC || t2 == Reg::PC || t == t2 || n == Reg::PC) { if (t == Reg::PC || t2 == Reg::PC || t == t2 || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -173,7 +174,7 @@ bool ThumbTranslatorVisitor::thumb32_LDREXD(Reg n, Reg t, Reg t2) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDREXH(Reg n, Reg t) { bool TranslatorVisitor::thumb32_LDREXH(Reg n, Reg t) {
if (t == Reg::PC || n == Reg::PC) { if (t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -185,7 +186,7 @@ bool ThumbTranslatorVisitor::thumb32_LDREXH(Reg n, Reg t) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) { if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -200,7 +201,7 @@ bool ThumbTranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_STREXB(Reg n, Reg t, Reg d) { bool TranslatorVisitor::thumb32_STREXB(Reg n, Reg t, Reg d) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) { if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -215,7 +216,7 @@ bool ThumbTranslatorVisitor::thumb32_STREXB(Reg n, Reg t, Reg d) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d) { bool TranslatorVisitor::thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d) {
if (d == Reg::PC || t == Reg::PC || t2 == Reg::PC || n == Reg::PC) { if (d == Reg::PC || t == Reg::PC || t2 == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -231,7 +232,7 @@ bool ThumbTranslatorVisitor::thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_STREXH(Reg n, Reg t, Reg d) { bool TranslatorVisitor::thumb32_STREXH(Reg n, Reg t, Reg d) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) { if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -246,11 +247,11 @@ bool ThumbTranslatorVisitor::thumb32_STREXH(Reg n, Reg t, Reg d) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_TBB(Reg n, Reg m) { bool TranslatorVisitor::thumb32_TBB(Reg n, Reg m) {
return TableBranch(*this, n, m, false); return TableBranch(*this, n, m, false);
} }
bool ThumbTranslatorVisitor::thumb32_TBH(Reg n, Reg m) { bool TranslatorVisitor::thumb32_TBH(Reg n, Reg m) {
return TableBranch(*this, n, m, true); return TableBranch(*this, n, m, true);
} }

View file

@ -3,8 +3,9 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h" #include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static bool ITBlockCheck(const A32::IREmitter& ir) { static bool ITBlockCheck(const A32::IREmitter& ir) {
@ -51,7 +52,7 @@ static bool STMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list) { bool TranslatorVisitor::thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list) {
const auto regs_imm = reg_list.ZeroExtend(); const auto regs_imm = reg_list.ZeroExtend();
const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm)); const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm));
@ -76,7 +77,7 @@ bool ThumbTranslatorVisitor::thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list) {
return LDMHelper(ir, W, n, regs_imm, start_address, start_address); return LDMHelper(ir, W, n, regs_imm, start_address, start_address);
} }
bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) { bool TranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) {
const auto regs_imm = reg_list.ZeroExtend(); const auto regs_imm = reg_list.ZeroExtend();
const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm)); const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm));
@ -101,15 +102,15 @@ bool ThumbTranslatorVisitor::thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list) {
return LDMHelper(ir, W, n, regs_imm, start_address, writeback_address); return LDMHelper(ir, W, n, regs_imm, start_address, writeback_address);
} }
bool ThumbTranslatorVisitor::thumb32_POP(Imm<16> reg_list) { bool TranslatorVisitor::thumb32_POP(Imm<16> reg_list) {
return thumb32_LDMIA(true, Reg::SP, reg_list); return thumb32_LDMIA(true, Reg::SP, reg_list);
} }
bool ThumbTranslatorVisitor::thumb32_PUSH(Imm<15> reg_list) { bool TranslatorVisitor::thumb32_PUSH(Imm<15> reg_list) {
return thumb32_STMDB(true, Reg::SP, reg_list); return thumb32_STMDB(true, Reg::SP, reg_list);
} }
bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) { bool TranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) {
const auto regs_imm = reg_list.ZeroExtend(); const auto regs_imm = reg_list.ZeroExtend();
const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm)); const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm));
@ -128,7 +129,7 @@ bool ThumbTranslatorVisitor::thumb32_STMIA(bool W, Reg n, Imm<15> reg_list) {
return STMHelper(ir, W, n, regs_imm, start_address, writeback_address); return STMHelper(ir, W, n, regs_imm, start_address, writeback_address);
} }
bool ThumbTranslatorVisitor::thumb32_STMDB(bool W, Reg n, Imm<15> reg_list) { bool TranslatorVisitor::thumb32_STMDB(bool W, Reg n, Imm<15> reg_list) {
const auto regs_imm = reg_list.ZeroExtend(); const auto regs_imm = reg_list.ZeroExtend();
const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm)); const auto num_regs = static_cast<u32>(Common::BitCount(regs_imm));

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static bool ITBlockCheck(const A32::IREmitter& ir) { static bool ITBlockCheck(const A32::IREmitter& ir) {
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock(); return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
} }
bool ThumbTranslatorVisitor::thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12) {
if (t == Reg::PC && ITBlockCheck(ir)) { if (t == Reg::PC && ITBlockCheck(ir)) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -31,7 +31,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8) {
if (!P && !W) { if (!P && !W) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -71,7 +71,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12) {
if (t == Reg::PC && ITBlockCheck(ir)) { if (t == Reg::PC && ITBlockCheck(ir)) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -92,7 +92,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
if (m == Reg::PC) { if (m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -117,7 +117,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_LDRT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_LDRT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution levels. // privileged execution levels.

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
namespace { namespace {
using DivideFunction = IR::U32U64 (IREmitter::*)(const IR::U32U64&, const IR::U32U64&); using DivideFunction = IR::U32U64 (IREmitter::*)(const IR::U32U64&, const IR::U32U64&);
bool DivideOperation(ThumbTranslatorVisitor& v, Reg d, Reg m, Reg n, DivideFunction fn) { bool DivideOperation(TranslatorVisitor& v, Reg d, Reg m, Reg n, DivideFunction fn) {
if (d == Reg::PC || m == Reg::PC || n == Reg::PC) { if (d == Reg::PC || m == Reg::PC || n == Reg::PC) {
return v.UnpredictableInstruction(); return v.UnpredictableInstruction();
} }
@ -23,11 +23,11 @@ bool DivideOperation(ThumbTranslatorVisitor& v, Reg d, Reg m, Reg n, DivideFunct
} }
} // Anonymous namespace } // Anonymous namespace
bool ThumbTranslatorVisitor::thumb32_SDIV(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SDIV(Reg n, Reg d, Reg m) {
return DivideOperation(*this, d, m, n, &IREmitter::SignedDiv); return DivideOperation(*this, d, m, n, &IREmitter::SignedDiv);
} }
bool ThumbTranslatorVisitor::thumb32_SMLAL(Reg n, Reg dLo, Reg dHi, Reg m) { bool TranslatorVisitor::thumb32_SMLAL(Reg n, Reg dLo, Reg dHi, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -49,7 +49,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLAL(Reg n, Reg dLo, Reg dHi, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLALD(Reg n, Reg dLo, Reg dHi, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMLALD(Reg n, Reg dLo, Reg dHi, bool M, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -79,7 +79,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLALD(Reg n, Reg dLo, Reg dHi, bool M, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLALXY(Reg n, Reg dLo, Reg dHi, bool N, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMLALXY(Reg n, Reg dLo, Reg dHi, bool N, bool M, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -103,7 +103,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLALXY(Reg n, Reg dLo, Reg dHi, bool N, bo
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLSLD(Reg n, Reg dLo, Reg dHi, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMLSLD(Reg n, Reg dLo, Reg dHi, bool M, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -133,7 +133,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLSLD(Reg n, Reg dLo, Reg dHi, bool M, Reg
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMULL(Reg n, Reg dLo, Reg dHi, Reg m) { bool TranslatorVisitor::thumb32_SMULL(Reg n, Reg dLo, Reg dHi, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -153,11 +153,11 @@ bool ThumbTranslatorVisitor::thumb32_SMULL(Reg n, Reg dLo, Reg dHi, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UDIV(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UDIV(Reg n, Reg d, Reg m) {
return DivideOperation(*this, d, m, n, &IREmitter::UnsignedDiv); return DivideOperation(*this, d, m, n, &IREmitter::UnsignedDiv);
} }
bool ThumbTranslatorVisitor::thumb32_UMLAL(Reg n, Reg dLo, Reg dHi, Reg m) { bool TranslatorVisitor::thumb32_UMLAL(Reg n, Reg dLo, Reg dHi, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -179,7 +179,7 @@ bool ThumbTranslatorVisitor::thumb32_UMLAL(Reg n, Reg dLo, Reg dHi, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UMULL(Reg n, Reg dLo, Reg dHi, Reg m) { bool TranslatorVisitor::thumb32_UMULL(Reg n, Reg dLo, Reg dHi, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -199,7 +199,7 @@ bool ThumbTranslatorVisitor::thumb32_UMULL(Reg n, Reg dLo, Reg dHi, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UMAAL(Reg n, Reg dLo, Reg dHi, Reg m) { bool TranslatorVisitor::thumb32_UMAAL(Reg n, Reg dLo, Reg dHi, Reg m) {
if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) { if (dLo == Reg::PC || dHi == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ThumbTranslatorVisitor::thumb32_CLZ(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_CLZ(Reg n, Reg d, Reg m) {
if (m != n || d == Reg::PC || m == Reg::PC) { if (m != n || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -19,7 +19,7 @@ bool ThumbTranslatorVisitor::thumb32_CLZ(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QADD(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QADD(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -33,7 +33,7 @@ bool ThumbTranslatorVisitor::thumb32_QADD(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QDADD(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QDADD(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -49,7 +49,7 @@ bool ThumbTranslatorVisitor::thumb32_QDADD(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QDSUB(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QDSUB(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -65,7 +65,7 @@ bool ThumbTranslatorVisitor::thumb32_QDSUB(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QSUB(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QSUB(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -79,7 +79,7 @@ bool ThumbTranslatorVisitor::thumb32_QSUB(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_RBIT(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_RBIT(Reg n, Reg d, Reg m) {
if (m != n || d == Reg::PC || m == Reg::PC) { if (m != n || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -104,7 +104,7 @@ bool ThumbTranslatorVisitor::thumb32_RBIT(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_REV(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_REV(Reg n, Reg d, Reg m) {
if (m != n || d == Reg::PC || m == Reg::PC) { if (m != n || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -115,7 +115,7 @@ bool ThumbTranslatorVisitor::thumb32_REV(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_REV16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_REV16(Reg n, Reg d, Reg m) {
if (m != n || d == Reg::PC || m == Reg::PC) { if (m != n || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -129,7 +129,7 @@ bool ThumbTranslatorVisitor::thumb32_REV16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_REVSH(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_REVSH(Reg n, Reg d, Reg m) {
if (m != n || d == Reg::PC || m == Reg::PC) { if (m != n || d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -141,7 +141,7 @@ bool ThumbTranslatorVisitor::thumb32_REVSH(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SEL(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SEL(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
bool ThumbTranslatorVisitor::thumb32_MLA(Reg n, Reg a, Reg d, Reg m) { bool TranslatorVisitor::thumb32_MLA(Reg n, Reg a, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -21,7 +21,7 @@ bool ThumbTranslatorVisitor::thumb32_MLA(Reg n, Reg a, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MLS(Reg n, Reg a, Reg d, Reg m) { bool TranslatorVisitor::thumb32_MLS(Reg n, Reg a, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -35,7 +35,7 @@ bool ThumbTranslatorVisitor::thumb32_MLS(Reg n, Reg a, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_MUL(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_MUL(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -48,7 +48,7 @@ bool ThumbTranslatorVisitor::thumb32_MUL(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLAD(Reg n, Reg a, Reg d, bool X, Reg m) { bool TranslatorVisitor::thumb32_SMLAD(Reg n, Reg a, Reg d, bool X, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -77,7 +77,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLAD(Reg n, Reg a, Reg d, bool X, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLSD(Reg n, Reg a, Reg d, bool X, Reg m) { bool TranslatorVisitor::thumb32_SMLSD(Reg n, Reg a, Reg d, bool X, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -104,7 +104,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLSD(Reg n, Reg a, Reg d, bool X, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLAXY(Reg n, Reg a, Reg d, bool N, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMLAXY(Reg n, Reg a, Reg d, bool N, bool M, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -123,7 +123,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLAXY(Reg n, Reg a, Reg d, bool N, bool M,
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMMLA(Reg n, Reg a, Reg d, bool R, Reg m) { bool TranslatorVisitor::thumb32_SMMLA(Reg n, Reg a, Reg d, bool R, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -142,7 +142,7 @@ bool ThumbTranslatorVisitor::thumb32_SMMLA(Reg n, Reg a, Reg d, bool R, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMMLS(Reg n, Reg a, Reg d, bool R, Reg m) { bool TranslatorVisitor::thumb32_SMMLS(Reg n, Reg a, Reg d, bool R, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -161,7 +161,7 @@ bool ThumbTranslatorVisitor::thumb32_SMMLS(Reg n, Reg a, Reg d, bool R, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMMUL(Reg n, Reg d, bool R, Reg m) { bool TranslatorVisitor::thumb32_SMMUL(Reg n, Reg d, bool R, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -179,7 +179,7 @@ bool ThumbTranslatorVisitor::thumb32_SMMUL(Reg n, Reg d, bool R, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMUAD(Reg n, Reg d, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMUAD(Reg n, Reg d, bool M, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -204,7 +204,7 @@ bool ThumbTranslatorVisitor::thumb32_SMUAD(Reg n, Reg d, bool M, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMUSD(Reg n, Reg d, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMUSD(Reg n, Reg d, bool M, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -228,7 +228,7 @@ bool ThumbTranslatorVisitor::thumb32_SMUSD(Reg n, Reg d, bool M, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMULXY(Reg n, Reg d, bool N, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMULXY(Reg n, Reg d, bool N, bool M, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -245,7 +245,7 @@ bool ThumbTranslatorVisitor::thumb32_SMULXY(Reg n, Reg d, bool N, bool M, Reg m)
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMLAWY(Reg n, Reg a, Reg d, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMLAWY(Reg n, Reg a, Reg d, bool M, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -264,7 +264,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLAWY(Reg n, Reg a, Reg d, bool M, Reg m)
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SMULWY(Reg n, Reg d, bool M, Reg m) { bool TranslatorVisitor::thumb32_SMULWY(Reg n, Reg d, bool M, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -281,7 +281,7 @@ bool ThumbTranslatorVisitor::thumb32_SMULWY(Reg n, Reg d, bool M, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_USAD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_USAD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -294,7 +294,7 @@ bool ThumbTranslatorVisitor::thumb32_USAD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_USADA8(Reg n, Reg a, Reg d, Reg m) { bool TranslatorVisitor::thumb32_USADA8(Reg n, Reg a, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC || a == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) { static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) {
@ -14,7 +14,7 @@ static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result); return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result);
} }
bool ThumbTranslatorVisitor::thumb32_SADD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -28,7 +28,7 @@ bool ThumbTranslatorVisitor::thumb32_SADD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SADD16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -42,7 +42,7 @@ bool ThumbTranslatorVisitor::thumb32_SADD16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SASX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SASX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -56,7 +56,7 @@ bool ThumbTranslatorVisitor::thumb32_SASX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SSAX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SSAX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -70,7 +70,7 @@ bool ThumbTranslatorVisitor::thumb32_SSAX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SSUB8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SSUB8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -84,7 +84,7 @@ bool ThumbTranslatorVisitor::thumb32_SSUB8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SSUB16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SSUB16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -98,7 +98,7 @@ bool ThumbTranslatorVisitor::thumb32_SSUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UADD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -112,7 +112,7 @@ bool ThumbTranslatorVisitor::thumb32_UADD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UADD16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -126,7 +126,7 @@ bool ThumbTranslatorVisitor::thumb32_UADD16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UASX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UASX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -140,7 +140,7 @@ bool ThumbTranslatorVisitor::thumb32_UASX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_USAX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_USAX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -154,7 +154,7 @@ bool ThumbTranslatorVisitor::thumb32_USAX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_USUB8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_USUB8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -168,7 +168,7 @@ bool ThumbTranslatorVisitor::thumb32_USUB8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_USUB16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_USUB16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -182,7 +182,7 @@ bool ThumbTranslatorVisitor::thumb32_USUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QADD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -195,7 +195,7 @@ bool ThumbTranslatorVisitor::thumb32_QADD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QADD16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -208,7 +208,7 @@ bool ThumbTranslatorVisitor::thumb32_QADD16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QASX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QASX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -227,7 +227,7 @@ bool ThumbTranslatorVisitor::thumb32_QASX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QSAX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QSAX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -246,7 +246,7 @@ bool ThumbTranslatorVisitor::thumb32_QSAX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QSUB8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QSUB8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -259,7 +259,7 @@ bool ThumbTranslatorVisitor::thumb32_QSUB8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_QSUB16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_QSUB16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -272,7 +272,7 @@ bool ThumbTranslatorVisitor::thumb32_QSUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UQADD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UQADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -285,7 +285,7 @@ bool ThumbTranslatorVisitor::thumb32_UQADD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UQADD16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UQADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -298,7 +298,7 @@ bool ThumbTranslatorVisitor::thumb32_UQADD16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UQASX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UQASX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -317,7 +317,7 @@ bool ThumbTranslatorVisitor::thumb32_UQASX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UQSAX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UQSAX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -336,7 +336,7 @@ bool ThumbTranslatorVisitor::thumb32_UQSAX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UQSUB8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UQSUB8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -349,7 +349,7 @@ bool ThumbTranslatorVisitor::thumb32_UQSUB8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UQSUB16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UQSUB16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -362,7 +362,7 @@ bool ThumbTranslatorVisitor::thumb32_UQSUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHADD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SHADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -375,7 +375,7 @@ bool ThumbTranslatorVisitor::thumb32_SHADD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHADD16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SHADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -388,7 +388,7 @@ bool ThumbTranslatorVisitor::thumb32_SHADD16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHASX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SHASX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -401,7 +401,7 @@ bool ThumbTranslatorVisitor::thumb32_SHASX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHSAX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SHSAX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -414,7 +414,7 @@ bool ThumbTranslatorVisitor::thumb32_SHSAX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHSUB8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SHSUB8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -427,7 +427,7 @@ bool ThumbTranslatorVisitor::thumb32_SHSUB8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHSUB16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_SHSUB16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -440,7 +440,7 @@ bool ThumbTranslatorVisitor::thumb32_SHSUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHADD8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UHADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -453,7 +453,7 @@ bool ThumbTranslatorVisitor::thumb32_UHADD8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHADD16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UHADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -466,7 +466,7 @@ bool ThumbTranslatorVisitor::thumb32_UHADD16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHASX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UHASX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -479,7 +479,7 @@ bool ThumbTranslatorVisitor::thumb32_UHASX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHSAX(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UHSAX(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -492,7 +492,7 @@ bool ThumbTranslatorVisitor::thumb32_UHSAX(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHSUB8(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UHSUB8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -505,7 +505,7 @@ bool ThumbTranslatorVisitor::thumb32_UHSUB8(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHSUB16(Reg n, Reg d, Reg m) { bool TranslatorVisitor::thumb32_UHSUB16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }

View file

@ -3,12 +3,12 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
template <typename StoreRegFn> template <typename StoreRegFn>
static bool StoreRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, StoreRegFn store_fn) { static bool StoreRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, StoreRegFn store_fn) {
if (n == Reg::PC) { if (n == Reg::PC) {
return v.UndefinedInstruction(); return v.UndefinedInstruction();
} }
@ -29,21 +29,21 @@ static bool StoreRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2,
return true; return true;
} }
using StoreImmFn = void (*)(ThumbTranslatorVisitor&, const IR::U32&, const IR::U32&); using StoreImmFn = void (*)(TranslatorVisitor&, const IR::U32&, const IR::U32&);
static void StoreImmByteFn(ThumbTranslatorVisitor& v, const IR::U32& address, const IR::U32& data) { static void StoreImmByteFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) {
v.ir.WriteMemory8(address, v.ir.LeastSignificantByte(data)); v.ir.WriteMemory8(address, v.ir.LeastSignificantByte(data));
} }
static void StoreImmHalfFn(ThumbTranslatorVisitor& v, const IR::U32& address, const IR::U32& data) { static void StoreImmHalfFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) {
v.ir.WriteMemory16(address, v.ir.LeastSignificantHalf(data)); v.ir.WriteMemory16(address, v.ir.LeastSignificantHalf(data));
} }
static void StoreImmWordFn(ThumbTranslatorVisitor& v, const IR::U32& address, const IR::U32& data) { static void StoreImmWordFn(TranslatorVisitor& v, const IR::U32& address, const IR::U32& data) {
v.ir.WriteMemory32(address, data); v.ir.WriteMemory32(address, data);
} }
static bool StoreImmediate(ThumbTranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, static bool StoreImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12,
StoreImmFn store_fn) { StoreImmFn store_fn) {
const auto imm32 = imm12.ZeroExtend(); const auto imm32 = imm12.ZeroExtend();
const auto reg_n = v.ir.GetRegister(n); const auto reg_n = v.ir.GetRegister(n);
@ -62,7 +62,7 @@ static bool StoreImmediate(ThumbTranslatorVisitor& v, Reg n, Reg t, bool P, bool
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_STRB_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRB_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -72,7 +72,7 @@ bool ThumbTranslatorVisitor::thumb32_STRB_imm_1(Reg n, Reg t, bool P, bool U, Im
return StoreImmediate(*this, n, t, P, U, true, Imm<12>{imm8.ZeroExtend()}, StoreImmByteFn); return StoreImmediate(*this, n, t, P, U, true, Imm<12>{imm8.ZeroExtend()}, StoreImmByteFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRB_imm_2(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRB_imm_2(Reg n, Reg t, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -82,7 +82,7 @@ bool ThumbTranslatorVisitor::thumb32_STRB_imm_2(Reg n, Reg t, Imm<8> imm8) {
return StoreImmediate(*this, n, t, true, false, false, Imm<12>{imm8.ZeroExtend()}, StoreImmByteFn); return StoreImmediate(*this, n, t, true, false, false, Imm<12>{imm8.ZeroExtend()}, StoreImmByteFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRB_imm_3(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_STRB_imm_3(Reg n, Reg t, Imm<12> imm12) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -92,7 +92,7 @@ bool ThumbTranslatorVisitor::thumb32_STRB_imm_3(Reg n, Reg t, Imm<12> imm12) {
return StoreImmediate(*this, n, t, true, true, false, imm12, StoreImmByteFn); return StoreImmediate(*this, n, t, true, true, false, imm12, StoreImmByteFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRBT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRBT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution levels. // privileged execution levels.
@ -109,13 +109,13 @@ bool ThumbTranslatorVisitor::thumb32_STRBT(Reg n, Reg t, Imm<8> imm8) {
return StoreImmediate(*this, n, t, true, true, false, Imm<12>{imm8.ZeroExtend()}, StoreImmByteFn); return StoreImmediate(*this, n, t, true, true, false, Imm<12>{imm8.ZeroExtend()}, StoreImmByteFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m) {
return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) { return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) {
ir.WriteMemory8(offset_address, ir.LeastSignificantByte(data)); ir.WriteMemory8(offset_address, ir.LeastSignificantByte(data));
}); });
} }
bool ThumbTranslatorVisitor::thumb32_STRH_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRH_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -125,7 +125,7 @@ bool ThumbTranslatorVisitor::thumb32_STRH_imm_1(Reg n, Reg t, bool P, bool U, Im
return StoreImmediate(*this, n, t, P, U, true, Imm<12>{imm8.ZeroExtend()}, StoreImmHalfFn); return StoreImmediate(*this, n, t, P, U, true, Imm<12>{imm8.ZeroExtend()}, StoreImmHalfFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRH_imm_2(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRH_imm_2(Reg n, Reg t, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -135,7 +135,7 @@ bool ThumbTranslatorVisitor::thumb32_STRH_imm_2(Reg n, Reg t, Imm<8> imm8) {
return StoreImmediate(*this, n, t, true, false, false, Imm<12>{imm8.ZeroExtend()}, StoreImmHalfFn); return StoreImmediate(*this, n, t, true, false, false, Imm<12>{imm8.ZeroExtend()}, StoreImmHalfFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRH_imm_3(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_STRH_imm_3(Reg n, Reg t, Imm<12> imm12) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -145,7 +145,7 @@ bool ThumbTranslatorVisitor::thumb32_STRH_imm_3(Reg n, Reg t, Imm<12> imm12) {
return StoreImmediate(*this, n, t, true, true, false, imm12, StoreImmHalfFn); return StoreImmediate(*this, n, t, true, true, false, imm12, StoreImmHalfFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRHT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRHT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution levels. // privileged execution levels.
@ -162,13 +162,13 @@ bool ThumbTranslatorVisitor::thumb32_STRHT(Reg n, Reg t, Imm<8> imm8) {
return StoreImmediate(*this, n, t, true, true, false, Imm<12>{imm8.ZeroExtend()}, StoreImmHalfFn); return StoreImmediate(*this, n, t, true, true, false, Imm<12>{imm8.ZeroExtend()}, StoreImmHalfFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRH(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_STRH(Reg n, Reg t, Imm<2> imm2, Reg m) {
return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) { return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) {
ir.WriteMemory16(offset_address, ir.LeastSignificantHalf(data)); ir.WriteMemory16(offset_address, ir.LeastSignificantHalf(data));
}); });
} }
bool ThumbTranslatorVisitor::thumb32_STR_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STR_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -178,7 +178,7 @@ bool ThumbTranslatorVisitor::thumb32_STR_imm_1(Reg n, Reg t, bool P, bool U, Imm
return StoreImmediate(*this, n, t, P, U, true, Imm<12>{imm8.ZeroExtend()}, StoreImmWordFn); return StoreImmediate(*this, n, t, P, U, true, Imm<12>{imm8.ZeroExtend()}, StoreImmWordFn);
} }
bool ThumbTranslatorVisitor::thumb32_STR_imm_2(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STR_imm_2(Reg n, Reg t, Imm<8> imm8) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -188,7 +188,7 @@ bool ThumbTranslatorVisitor::thumb32_STR_imm_2(Reg n, Reg t, Imm<8> imm8) {
return StoreImmediate(*this, n, t, true, false, false, Imm<12>{imm8.ZeroExtend()}, StoreImmWordFn); return StoreImmediate(*this, n, t, true, false, false, Imm<12>{imm8.ZeroExtend()}, StoreImmWordFn);
} }
bool ThumbTranslatorVisitor::thumb32_STR_imm_3(Reg n, Reg t, Imm<12> imm12) { bool TranslatorVisitor::thumb32_STR_imm_3(Reg n, Reg t, Imm<12> imm12) {
if (n == Reg::PC) { if (n == Reg::PC) {
return UndefinedInstruction(); return UndefinedInstruction();
} }
@ -198,7 +198,7 @@ bool ThumbTranslatorVisitor::thumb32_STR_imm_3(Reg n, Reg t, Imm<12> imm12) {
return StoreImmediate(*this, n, t, true, true, false, imm12, StoreImmWordFn); return StoreImmediate(*this, n, t, true, true, false, imm12, StoreImmWordFn);
} }
bool ThumbTranslatorVisitor::thumb32_STRT(Reg n, Reg t, Imm<8> imm8) { bool TranslatorVisitor::thumb32_STRT(Reg n, Reg t, Imm<8> imm8) {
// TODO: Add an unpredictable instruction path if this // TODO: Add an unpredictable instruction path if this
// is executed in hypervisor mode if we ever support // is executed in hypervisor mode if we ever support
// privileged execution levels. // privileged execution levels.
@ -215,7 +215,7 @@ bool ThumbTranslatorVisitor::thumb32_STRT(Reg n, Reg t, Imm<8> imm8) {
return StoreImmediate(*this, n, t, true, true, false, Imm<12>{imm8.ZeroExtend()}, StoreImmWordFn); return StoreImmediate(*this, n, t, true, true, false, Imm<12>{imm8.ZeroExtend()}, StoreImmWordFn);
} }
bool ThumbTranslatorVisitor::thumb32_STR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) { bool TranslatorVisitor::thumb32_STR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) { return StoreRegister(*this, n, t, imm2, m, [this](const IR::U32& offset_address, const IR::U32& data) {
ir.WriteMemory32(offset_address, data); ir.WriteMemory32(offset_address, data);
}); });

View file

@ -0,0 +1,109 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include <dynarmic/A32/config.h>
#include "common/assert.h"
namespace Dynarmic::A32 {
bool TranslatorVisitor::ArmConditionPassed(Cond cond) {
return IsConditionPassed(cond, cond_state, ir, 4);
}
bool TranslatorVisitor::ThumbConditionPassed() {
const Cond cond = ir.current_location.IT().Cond();
return IsConditionPassed(cond, cond_state, ir, static_cast<int>(current_instruction_size));
}
bool TranslatorVisitor::VFPConditionPassed(Cond cond) {
if (ir.current_location.TFlag()) {
ASSERT(cond == Cond::AL);
return true;
}
return ArmConditionPassed(cond);
}
bool TranslatorVisitor::InterpretThisInstruction() {
ir.SetTerm(IR::Term::Interpret(ir.current_location));
return false;
}
bool TranslatorVisitor::UnpredictableInstruction() {
return RaiseException(Exception::UnpredictableInstruction);
}
bool TranslatorVisitor::UndefinedInstruction() {
return RaiseException(Exception::UndefinedInstruction);
}
bool TranslatorVisitor::DecodeError() {
return RaiseException(Exception::DecodeError);
}
bool TranslatorVisitor::RaiseException(Exception exception) {
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + static_cast<u32>(current_instruction_size)));
ir.ExceptionRaised(exception);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
IR::UAny TranslatorVisitor::I(size_t bitsize, u64 value) {
switch (bitsize) {
case 8:
return ir.Imm8(static_cast<u8>(value));
case 16:
return ir.Imm16(static_cast<u16>(value));
case 32:
return ir.Imm32(static_cast<u32>(value));
case 64:
return ir.Imm64(value);
default:
ASSERT_FALSE("Imm - get: Invalid bitsize");
}
}
IR::ResultAndCarry<IR::U32> TranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<3> imm3, Imm<2> imm2, IR::U1 carry_in) {
return EmitImmShift(value, type, concatenate(imm3, imm2), carry_in);
}
IR::ResultAndCarry<IR::U32> TranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in) {
u8 imm5_value = imm5.ZeroExtend<u8>();
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::LSR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.LogicalShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ASR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.ArithmeticShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ROR:
if (imm5_value) {
return ir.RotateRight(value, ir.Imm8(imm5_value), carry_in);
} else {
return ir.RotateRightExtended(value, carry_in);
}
}
UNREACHABLE();
}
IR::ResultAndCarry<IR::U32> TranslatorVisitor::EmitRegShift(IR::U32 value, ShiftType type, IR::U8 amount, IR::U1 carry_in) {
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, amount, carry_in);
case ShiftType::LSR:
return ir.LogicalShiftRight(value, amount, carry_in);
case ShiftType::ASR:
return ir.ArithmeticShiftRight(value, amount, carry_in);
case ShiftType::ROR:
return ir.RotateRight(value, amount, carry_in);
}
UNREACHABLE();
}
} // namespace Dynarmic::A32

View file

@ -18,28 +18,29 @@ namespace Dynarmic::A32 {
enum class Exception; enum class Exception;
struct ArmTranslatorVisitor final { struct TranslatorVisitor final {
using instruction_return_type = bool; using instruction_return_type = bool;
explicit ArmTranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options) : ir(block, descriptor, options.arch_version), options(options) { explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options)
ASSERT_MSG(!descriptor.TFlag(), "The processor must be in Arm mode"); : ir(block, descriptor, options.arch_version), options(options)
} {}
A32::IREmitter ir; A32::IREmitter ir;
ConditionalState cond_state = ConditionalState::None; ConditionalState cond_state = ConditionalState::None;
TranslationOptions options; TranslationOptions options;
bool ConditionPassed(Cond cond); size_t current_instruction_size;
bool ArmConditionPassed(Cond cond);
bool ThumbConditionPassed();
bool VFPConditionPassed(Cond cond);
bool InterpretThisInstruction(); bool InterpretThisInstruction();
bool UnpredictableInstruction(); bool UnpredictableInstruction();
bool UndefinedInstruction(); bool UndefinedInstruction();
bool DecodeError(); bool DecodeError();
bool RaiseException(Exception exception); bool RaiseException(Exception exception);
static u32 ArmExpandImm(int rotate, Imm<8> imm8) {
return Common::RotateRight<u32>(imm8.ZeroExtend(), rotate * 2);
}
struct ImmAndCarry { struct ImmAndCarry {
u32 imm32; u32 imm32;
IR::U1 carry; IR::U1 carry;
@ -49,15 +50,47 @@ struct ArmTranslatorVisitor final {
u32 imm32 = imm8.ZeroExtend(); u32 imm32 = imm8.ZeroExtend();
auto carry_out = carry_in; auto carry_out = carry_in;
if (rotate) { if (rotate) {
imm32 = ArmExpandImm(rotate, imm8); imm32 = Common::RotateRight<u32>(imm8.ZeroExtend(), rotate * 2);
carry_out = ir.Imm1(Common::Bit<31>(imm32)); carry_out = ir.Imm1(Common::Bit<31>(imm32));
} }
return {imm32, carry_out}; return {imm32, carry_out};
} }
u32 ArmExpandImm(int rotate, Imm<8> imm8) {
return ArmExpandImm_C(rotate, imm8, ir.Imm1(0)).imm32;
}
ImmAndCarry ThumbExpandImm_C(Imm<1> i, Imm<3> imm3, Imm<8> imm8, IR::U1 carry_in) {
const Imm<12> imm12 = concatenate(i, imm3, imm8);
if (imm12.Bits<10, 11>() == 0) {
const u32 imm32 = [&]{
const u32 imm8 = imm12.Bits<0, 7>();
switch (imm12.Bits<8, 9>()) {
case 0b00:
return imm8;
case 0b01:
return Common::Replicate(imm8, 16);
case 0b10:
return Common::Replicate(imm8 << 8, 16);
case 0b11:
return Common::Replicate(imm8, 8);
}
UNREACHABLE();
}();
return {imm32, carry_in};
}
const u32 imm32 = Common::RotateRight<u32>((1 << 7) | imm12.Bits<0, 6>(), imm12.Bits<7, 11>());
return {imm32, ir.Imm1(Common::Bit<31>(imm32))};
}
u32 ThumbExpandImm(Imm<1> i, Imm<3> imm3, Imm<8> imm8) {
return ThumbExpandImm_C(i, imm3, imm8, ir.Imm1(0)).imm32;
}
// Creates an immediate of the given value // Creates an immediate of the given value
IR::UAny I(size_t bitsize, u64 value); IR::UAny I(size_t bitsize, u64 value);
IR::ResultAndCarry<IR::U32> EmitImmShift(IR::U32 value, ShiftType type, Imm<3> imm3, Imm<2> imm2, IR::U1 carry_in);
IR::ResultAndCarry<IR::U32> EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in); IR::ResultAndCarry<IR::U32> EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in);
IR::ResultAndCarry<IR::U32> EmitRegShift(IR::U32 value, ShiftType type, IR::U8 amount, IR::U1 carry_in); IR::ResultAndCarry<IR::U32> EmitRegShift(IR::U32 value, ShiftType type, IR::U8 amount, IR::U1 carry_in);
template <typename FnT> bool EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, ExtReg m, const FnT& fn); template <typename FnT> bool EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, ExtReg m, const FnT& fn);
@ -369,6 +402,342 @@ struct ArmTranslatorVisitor final {
bool arm_SETEND(bool E); bool arm_SETEND(bool E);
bool arm_SRS(); bool arm_SRS();
// thumb16
bool thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d);
bool thumb16_LSR_imm(Imm<5> imm5, Reg m, Reg d);
bool thumb16_ASR_imm(Imm<5> imm5, Reg m, Reg d);
bool thumb16_ADD_reg_t1(Reg m, Reg n, Reg d);
bool thumb16_SUB_reg(Reg m, Reg n, Reg d);
bool thumb16_ADD_imm_t1(Imm<3> imm3, Reg n, Reg d);
bool thumb16_SUB_imm_t1(Imm<3> imm3, Reg n, Reg d);
bool thumb16_MOV_imm(Reg d, Imm<8> imm8);
bool thumb16_CMP_imm(Reg n, Imm<8> imm8);
bool thumb16_ADD_imm_t2(Reg d_n, Imm<8> imm8);
bool thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8);
bool thumb16_AND_reg(Reg m, Reg d_n);
bool thumb16_EOR_reg(Reg m, Reg d_n);
bool thumb16_LSL_reg(Reg m, Reg d_n);
bool thumb16_LSR_reg(Reg m, Reg d_n);
bool thumb16_ASR_reg(Reg m, Reg d_n);
bool thumb16_ADC_reg(Reg m, Reg d_n);
bool thumb16_SBC_reg(Reg m, Reg d_n);
bool thumb16_ROR_reg(Reg m, Reg d_n);
bool thumb16_TST_reg(Reg m, Reg n);
bool thumb16_RSB_imm(Reg n, Reg d);
bool thumb16_CMP_reg_t1(Reg m, Reg n);
bool thumb16_CMN_reg(Reg m, Reg n);
bool thumb16_ORR_reg(Reg m, Reg d_n);
bool thumb16_MUL_reg(Reg n, Reg d_m);
bool thumb16_BIC_reg(Reg m, Reg d_n);
bool thumb16_MVN_reg(Reg m, Reg d);
bool thumb16_ADD_reg_t2(bool d_n_hi, Reg m, Reg d_n_lo);
bool thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo);
bool thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo);
bool thumb16_LDR_literal(Reg t, Imm<8> imm8);
bool thumb16_STR_reg(Reg m, Reg n, Reg t);
bool thumb16_STRH_reg(Reg m, Reg n, Reg t);
bool thumb16_STRB_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRSB_reg(Reg m, Reg n, Reg t);
bool thumb16_LDR_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRH_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRB_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRSH_reg(Reg m, Reg n, Reg t);
bool thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t);
bool thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t);
bool thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_STR_imm_t2(Reg t, Imm<8> imm8);
bool thumb16_LDR_imm_t2(Reg t, Imm<8> imm8);
bool thumb16_ADR(Reg d, Imm<8> imm8);
bool thumb16_ADD_sp_t1(Reg d, Imm<8> imm8);
bool thumb16_ADD_sp_t2(Imm<7> imm7);
bool thumb16_SUB_sp(Imm<7> imm7);
bool thumb16_SEV();
bool thumb16_SEVL();
bool thumb16_WFE();
bool thumb16_WFI();
bool thumb16_YIELD();
bool thumb16_NOP();
bool thumb16_IT(Imm<8> imm8);
bool thumb16_SXTH(Reg m, Reg d);
bool thumb16_SXTB(Reg m, Reg d);
bool thumb16_UXTH(Reg m, Reg d);
bool thumb16_UXTB(Reg m, Reg d);
bool thumb16_PUSH(bool M, RegList reg_list);
bool thumb16_POP(bool P, RegList reg_list);
bool thumb16_SETEND(bool E);
bool thumb16_CPS(bool, bool, bool, bool);
bool thumb16_REV(Reg m, Reg d);
bool thumb16_REV16(Reg m, Reg d);
bool thumb16_REVSH(Reg m, Reg d);
bool thumb16_BKPT(Imm<8> imm8);
bool thumb16_STMIA(Reg n, RegList reg_list);
bool thumb16_LDMIA(Reg n, RegList reg_list);
bool thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm5, Reg n);
bool thumb16_UDF();
bool thumb16_BX(Reg m);
bool thumb16_BLX_reg(Reg m);
bool thumb16_SVC(Imm<8> imm8);
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
bool thumb16_B_t2(Imm<11> imm11);
// thumb32 load/store multiple instructions
bool thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list);
bool thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list);
bool thumb32_POP(Imm<16> reg_list);
bool thumb32_PUSH(Imm<15> reg_list);
bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list);
bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);
// thumb32 load/store dual, load/store exclusive, table branch instructions
bool thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDREX(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDREXD(Reg n, Reg t, Reg t2);
bool thumb32_LDREXB(Reg n, Reg t);
bool thumb32_LDREXH(Reg n, Reg t);
bool thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8);
bool thumb32_STREXB(Reg n, Reg t, Reg d);
bool thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d);
bool thumb32_STREXH(Reg n, Reg t, Reg d);
bool thumb32_TBB(Reg n, Reg m);
bool thumb32_TBH(Reg n, Reg m);
// thumb32 data processing (shifted register) instructions
bool thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_BIC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_PKH(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<1> tb, Reg m);
bool thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ADC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_RSB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
// thumb32 data processing (modified immediate) instructions
bool thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_BIC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_RSB_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
// thumb32 data processing (plain binary immediate) instructions.
bool thumb32_ADR_t2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ADR_t3(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ADD_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_BFC(Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb);
bool thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb);
bool thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1);
bool thumb32_SSAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm);
bool thumb32_SSAT16(Reg n, Reg d, Imm<4> sat_imm);
bool thumb32_SUB_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1);
bool thumb32_USAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm);
bool thumb32_USAT16(Reg n, Reg d, Imm<4> sat_imm);
// thumb32 miscellaneous control instructions
bool thumb32_BXJ(Reg m);
bool thumb32_CLREX();
bool thumb32_DMB(Imm<4> option);
bool thumb32_DSB(Imm<4> option);
bool thumb32_ISB(Imm<4> option);
bool thumb32_NOP();
bool thumb32_SEV();
bool thumb32_SEVL();
bool thumb32_UDF();
bool thumb32_WFE();
bool thumb32_WFI();
bool thumb32_YIELD();
// thumb32 branch instructions
bool thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
// thumb32 store single data item instructions
bool thumb32_STRB_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8);
bool thumb32_STRB_imm_2(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRB_imm_3(Reg n, Reg t, Imm<12> imm12);
bool thumb32_STRBT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_STRH_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8);
bool thumb32_STRH_imm_2(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRH_imm_3(Reg n, Reg t, Imm<12> imm12);
bool thumb32_STRHT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRH(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_STR_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8);
bool thumb32_STR_imm_2(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STR_imm_3(Reg n, Reg t, Imm<12> imm12);
bool thumb32_STRT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STR_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
// thumb32 load byte and memory hints
bool thumb32_PLD_lit(bool U, Imm<12> imm12);
bool thumb32_PLD_imm8(bool W, Reg n, Imm<8> imm8);
bool thumb32_PLD_imm12(bool W, Reg n, Imm<12> imm12);
bool thumb32_PLD_reg(bool W, Reg n, Imm<2> imm2, Reg m);
bool thumb32_PLI_lit(bool U, Imm<12> imm12);
bool thumb32_PLI_imm8(Reg n, Imm<8> imm8);
bool thumb32_PLI_imm12(Reg n, Imm<12> imm12);
bool thumb32_PLI_reg(Reg n, Imm<2> imm2, Reg m);
bool thumb32_LDRB_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRB_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRB_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRBT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDRSB_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRSB_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRSB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRSB_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRSBT(Reg n, Reg t, Imm<8> imm8);
// thumb32 load halfword instructions
bool thumb32_LDRH_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRH_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRH_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRHT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDRSH_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRSH_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRSH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRSH_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRSHT(Reg n, Reg t, Imm<8> imm8);
// thumb32 load word instructions
bool thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRT(Reg n, Reg t, Imm<8> imm8);
// thumb32 data processing (register) instructions
bool thumb32_ASR_reg(Reg m, Reg d, Reg s);
bool thumb32_LSL_reg(Reg m, Reg d, Reg s);
bool thumb32_LSR_reg(Reg m, Reg d, Reg s);
bool thumb32_ROR_reg(Reg m, Reg d, Reg s);
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTH(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTB16(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTH(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m);
// thumb32 long multiply, long multiply accumulate, and divide instructions
bool thumb32_SDIV(Reg n, Reg d, Reg m);
bool thumb32_SMLAL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_SMLALD(Reg n, Reg dLo, Reg dHi, bool M, Reg m);
bool thumb32_SMLALXY(Reg n, Reg dLo, Reg dHi, bool N, bool M, Reg m);
bool thumb32_SMLSLD(Reg n, Reg dLo, Reg dHi, bool M, Reg m);
bool thumb32_SMULL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_UDIV(Reg n, Reg d, Reg m);
bool thumb32_UMAAL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_UMLAL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_UMULL(Reg n, Reg dLo, Reg dHi, Reg m);
// thumb32 miscellaneous instructions
bool thumb32_CLZ(Reg n, Reg d, Reg m);
bool thumb32_QADD(Reg n, Reg d, Reg m);
bool thumb32_QDADD(Reg n, Reg d, Reg m);
bool thumb32_QDSUB(Reg n, Reg d, Reg m);
bool thumb32_QSUB(Reg n, Reg d, Reg m);
bool thumb32_RBIT(Reg n, Reg d, Reg m);
bool thumb32_REV(Reg n, Reg d, Reg m);
bool thumb32_REV16(Reg n, Reg d, Reg m);
bool thumb32_REVSH(Reg n, Reg d, Reg m);
bool thumb32_SEL(Reg n, Reg d, Reg m);
// thumb32 multiply instructions
bool thumb32_MLA(Reg n, Reg a, Reg d, Reg m);
bool thumb32_MLS(Reg n, Reg a, Reg d, Reg m);
bool thumb32_MUL(Reg n, Reg d, Reg m);
bool thumb32_SMLAD(Reg n, Reg a, Reg d, bool X, Reg m);
bool thumb32_SMLAXY(Reg n, Reg a, Reg d, bool N, bool M, Reg m);
bool thumb32_SMLAWY(Reg n, Reg a, Reg d, bool M, Reg m);
bool thumb32_SMLSD(Reg n, Reg a, Reg d, bool X, Reg m);
bool thumb32_SMMLA(Reg n, Reg a, Reg d, bool R, Reg m);
bool thumb32_SMMLS(Reg n, Reg a, Reg d, bool R, Reg m);
bool thumb32_SMMUL(Reg n, Reg d, bool R, Reg m);
bool thumb32_SMUAD(Reg n, Reg d, bool M, Reg m);
bool thumb32_SMUSD(Reg n, Reg d, bool M, Reg m);
bool thumb32_SMULXY(Reg n, Reg d, bool N, bool M, Reg m);
bool thumb32_SMULWY(Reg n, Reg d, bool M, Reg m);
bool thumb32_USAD8(Reg n, Reg d, Reg m);
bool thumb32_USADA8(Reg n, Reg a, Reg d, Reg m);
// thumb32 parallel add/sub instructions
bool thumb32_SADD8(Reg n, Reg d, Reg m);
bool thumb32_SADD16(Reg n, Reg d, Reg m);
bool thumb32_SASX(Reg n, Reg d, Reg m);
bool thumb32_SSAX(Reg n, Reg d, Reg m);
bool thumb32_SSUB8(Reg n, Reg d, Reg m);
bool thumb32_SSUB16(Reg n, Reg d, Reg m);
bool thumb32_UADD8(Reg n, Reg d, Reg m);
bool thumb32_UADD16(Reg n, Reg d, Reg m);
bool thumb32_UASX(Reg n, Reg d, Reg m);
bool thumb32_USAX(Reg n, Reg d, Reg m);
bool thumb32_USUB8(Reg n, Reg d, Reg m);
bool thumb32_USUB16(Reg n, Reg d, Reg m);
bool thumb32_QADD8(Reg n, Reg d, Reg m);
bool thumb32_QADD16(Reg n, Reg d, Reg m);
bool thumb32_QASX(Reg n, Reg d, Reg m);
bool thumb32_QSAX(Reg n, Reg d, Reg m);
bool thumb32_QSUB8(Reg n, Reg d, Reg m);
bool thumb32_QSUB16(Reg n, Reg d, Reg m);
bool thumb32_UQADD8(Reg n, Reg d, Reg m);
bool thumb32_UQADD16(Reg n, Reg d, Reg m);
bool thumb32_UQASX(Reg n, Reg d, Reg m);
bool thumb32_UQSAX(Reg n, Reg d, Reg m);
bool thumb32_UQSUB8(Reg n, Reg d, Reg m);
bool thumb32_UQSUB16(Reg n, Reg d, Reg m);
bool thumb32_SHADD8(Reg n, Reg d, Reg m);
bool thumb32_SHADD16(Reg n, Reg d, Reg m);
bool thumb32_SHASX(Reg n, Reg d, Reg m);
bool thumb32_SHSAX(Reg n, Reg d, Reg m);
bool thumb32_SHSUB8(Reg n, Reg d, Reg m);
bool thumb32_SHSUB16(Reg n, Reg d, Reg m);
bool thumb32_UHADD8(Reg n, Reg d, Reg m);
bool thumb32_UHADD16(Reg n, Reg d, Reg m);
bool thumb32_UHASX(Reg n, Reg d, Reg m);
bool thumb32_UHSAX(Reg n, Reg d, Reg m);
bool thumb32_UHSUB8(Reg n, Reg d, Reg m);
bool thumb32_UHSUB16(Reg n, Reg d, Reg m);
// Floating-point three-register data processing instructions // Floating-point three-register data processing instructions
bool vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm); bool vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
bool vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm); bool vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);

View file

@ -1,430 +0,0 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include "common/assert.h"
#include "frontend/imm.h"
#include "frontend/A32/ir_emitter.h"
#include "frontend/A32/location_descriptor.h"
#include "frontend/A32/translate/conditional_state.h"
#include "frontend/A32/translate/translate.h"
#include "frontend/A32/types.h"
namespace Dynarmic::A32 {
enum class Exception;
struct ThumbTranslatorVisitor final {
using instruction_return_type = bool;
explicit ThumbTranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options) : ir(block, descriptor, options.arch_version), options(options) {
ASSERT_MSG(descriptor.TFlag(), "The processor must be in Thumb mode");
}
struct ImmAndCarry {
u32 imm32;
IR::U1 carry;
};
ImmAndCarry ThumbExpandImm_C(Imm<1> i, Imm<3> imm3, Imm<8> imm8, IR::U1 carry_in) {
const Imm<12> imm12 = concatenate(i, imm3, imm8);
if (imm12.Bits<10, 11>() == 0) {
const u32 imm32 = [&]{
const u32 imm8 = imm12.Bits<0, 7>();
switch (imm12.Bits<8, 9>()) {
case 0b00:
return imm8;
case 0b01:
return Common::Replicate(imm8, 16);
case 0b10:
return Common::Replicate(imm8 << 8, 16);
case 0b11:
return Common::Replicate(imm8, 8);
}
UNREACHABLE();
}();
return {imm32, carry_in};
}
const u32 imm32 = Common::RotateRight<u32>((1 << 7) | imm12.Bits<0, 6>(), imm12.Bits<7, 11>());
return {imm32, ir.Imm1(Common::Bit<31>(imm32))};
}
u32 ThumbExpandImm(Imm<1> i, Imm<3> imm3, Imm<8> imm8) {
return ThumbExpandImm_C(i, imm3, imm8, ir.Imm1(0)).imm32;
}
IR::ResultAndCarry<IR::U32> EmitImmShift(IR::U32 value, ShiftType type, Imm<3> imm3, Imm<2> imm2, IR::U1 carry_in) {
u8 imm5_value = concatenate(imm3, imm2).ZeroExtend<u8>();
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::LSR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.LogicalShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ASR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.ArithmeticShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ROR:
if (imm5_value) {
return ir.RotateRight(value, ir.Imm8(imm5_value), carry_in);
} else {
return ir.RotateRightExtended(value, carry_in);
}
}
UNREACHABLE();
}
A32::IREmitter ir;
ConditionalState cond_state = ConditionalState::None;
TranslationOptions options;
bool ConditionPassed(bool is_thumb_16);
bool InterpretThisInstruction();
bool UnpredictableInstruction();
bool UndefinedInstruction();
bool RaiseException(Exception exception);
IR::ResultAndCarry<IR::U32> EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in);
// thumb16
bool thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d);
bool thumb16_LSR_imm(Imm<5> imm5, Reg m, Reg d);
bool thumb16_ASR_imm(Imm<5> imm5, Reg m, Reg d);
bool thumb16_ADD_reg_t1(Reg m, Reg n, Reg d);
bool thumb16_SUB_reg(Reg m, Reg n, Reg d);
bool thumb16_ADD_imm_t1(Imm<3> imm3, Reg n, Reg d);
bool thumb16_SUB_imm_t1(Imm<3> imm3, Reg n, Reg d);
bool thumb16_MOV_imm(Reg d, Imm<8> imm8);
bool thumb16_CMP_imm(Reg n, Imm<8> imm8);
bool thumb16_ADD_imm_t2(Reg d_n, Imm<8> imm8);
bool thumb16_SUB_imm_t2(Reg d_n, Imm<8> imm8);
bool thumb16_AND_reg(Reg m, Reg d_n);
bool thumb16_EOR_reg(Reg m, Reg d_n);
bool thumb16_LSL_reg(Reg m, Reg d_n);
bool thumb16_LSR_reg(Reg m, Reg d_n);
bool thumb16_ASR_reg(Reg m, Reg d_n);
bool thumb16_ADC_reg(Reg m, Reg d_n);
bool thumb16_SBC_reg(Reg m, Reg d_n);
bool thumb16_ROR_reg(Reg m, Reg d_n);
bool thumb16_TST_reg(Reg m, Reg n);
bool thumb16_RSB_imm(Reg n, Reg d);
bool thumb16_CMP_reg_t1(Reg m, Reg n);
bool thumb16_CMN_reg(Reg m, Reg n);
bool thumb16_ORR_reg(Reg m, Reg d_n);
bool thumb16_MUL_reg(Reg n, Reg d_m);
bool thumb16_BIC_reg(Reg m, Reg d_n);
bool thumb16_MVN_reg(Reg m, Reg d);
bool thumb16_ADD_reg_t2(bool d_n_hi, Reg m, Reg d_n_lo);
bool thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo);
bool thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo);
bool thumb16_LDR_literal(Reg t, Imm<8> imm8);
bool thumb16_STR_reg(Reg m, Reg n, Reg t);
bool thumb16_STRH_reg(Reg m, Reg n, Reg t);
bool thumb16_STRB_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRSB_reg(Reg m, Reg n, Reg t);
bool thumb16_LDR_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRH_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRB_reg(Reg m, Reg n, Reg t);
bool thumb16_LDRSH_reg(Reg m, Reg n, Reg t);
bool thumb16_STR_imm_t1(Imm<5> imm5, Reg n, Reg t);
bool thumb16_LDR_imm_t1(Imm<5> imm5, Reg n, Reg t);
bool thumb16_STRB_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_LDRB_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_STRH_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_LDRH_imm(Imm<5> imm5, Reg n, Reg t);
bool thumb16_STR_imm_t2(Reg t, Imm<8> imm8);
bool thumb16_LDR_imm_t2(Reg t, Imm<8> imm8);
bool thumb16_ADR(Reg d, Imm<8> imm8);
bool thumb16_ADD_sp_t1(Reg d, Imm<8> imm8);
bool thumb16_ADD_sp_t2(Imm<7> imm7);
bool thumb16_SUB_sp(Imm<7> imm7);
bool thumb16_SEV();
bool thumb16_SEVL();
bool thumb16_WFE();
bool thumb16_WFI();
bool thumb16_YIELD();
bool thumb16_NOP();
bool thumb16_IT(Imm<8> imm8);
bool thumb16_SXTH(Reg m, Reg d);
bool thumb16_SXTB(Reg m, Reg d);
bool thumb16_UXTH(Reg m, Reg d);
bool thumb16_UXTB(Reg m, Reg d);
bool thumb16_PUSH(bool M, RegList reg_list);
bool thumb16_POP(bool P, RegList reg_list);
bool thumb16_SETEND(bool E);
bool thumb16_CPS(bool, bool, bool, bool);
bool thumb16_REV(Reg m, Reg d);
bool thumb16_REV16(Reg m, Reg d);
bool thumb16_REVSH(Reg m, Reg d);
bool thumb16_BKPT([[maybe_unused]] Imm<8> imm8);
bool thumb16_STMIA(Reg n, RegList reg_list);
bool thumb16_LDMIA(Reg n, RegList reg_list);
bool thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm5, Reg n);
bool thumb16_UDF();
bool thumb16_BX(Reg m);
bool thumb16_BLX_reg(Reg m);
bool thumb16_SVC(Imm<8> imm8);
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
bool thumb16_B_t2(Imm<11> imm11);
// thumb32 load/store multiple instructions
bool thumb32_LDMDB(bool W, Reg n, Imm<16> reg_list);
bool thumb32_LDMIA(bool W, Reg n, Imm<16> reg_list);
bool thumb32_POP(Imm<16> reg_list);
bool thumb32_PUSH(Imm<15> reg_list);
bool thumb32_STMIA(bool W, Reg n, Imm<15> reg_list);
bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);
// thumb32 load/store dual, load/store exclusive, table branch instructions
bool thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDREX(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDREXD(Reg n, Reg t, Reg t2);
bool thumb32_LDREXB(Reg n, Reg t);
bool thumb32_LDREXH(Reg n, Reg t);
bool thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8);
bool thumb32_STREXB(Reg n, Reg t, Reg d);
bool thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d);
bool thumb32_STREXH(Reg n, Reg t, Reg d);
bool thumb32_TBB(Reg n, Reg m);
bool thumb32_TBH(Reg n, Reg m);
// thumb32 data processing (shifted register) instructions
bool thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_BIC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_PKH(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<1> tb, Reg m);
bool thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_ADC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
bool thumb32_RSB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m);
// thumb32 data processing (modified immediate) instructions
bool thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_BIC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ADC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_SBC_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_RSB_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
// thumb32 data processing (plain binary immediate) instructions.
bool thumb32_ADR_t2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ADR_t3(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_ADD_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_BFC(Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb);
bool thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb);
bool thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1);
bool thumb32_SSAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm);
bool thumb32_SSAT16(Reg n, Reg d, Imm<4> sat_imm);
bool thumb32_SUB_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm<8> imm8);
bool thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1);
bool thumb32_USAT(bool sh, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> sat_imm);
bool thumb32_USAT16(Reg n, Reg d, Imm<4> sat_imm);
// thumb32 miscellaneous control instructions
bool thumb32_BXJ(Reg m);
bool thumb32_CLREX();
bool thumb32_DMB(Imm<4> option);
bool thumb32_DSB(Imm<4> option);
bool thumb32_ISB(Imm<4> option);
bool thumb32_NOP();
bool thumb32_SEV();
bool thumb32_SEVL();
bool thumb32_UDF();
bool thumb32_WFE();
bool thumb32_WFI();
bool thumb32_YIELD();
// thumb32 branch instructions
bool thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
bool thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
// thumb32 store single data item instructions
bool thumb32_STRB_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8);
bool thumb32_STRB_imm_2(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRB_imm_3(Reg n, Reg t, Imm<12> imm12);
bool thumb32_STRBT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRB(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_STRH_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8);
bool thumb32_STRH_imm_2(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRH_imm_3(Reg n, Reg t, Imm<12> imm12);
bool thumb32_STRHT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STRH(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_STR_imm_1(Reg n, Reg t, bool P, bool U, Imm<8> imm8);
bool thumb32_STR_imm_2(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STR_imm_3(Reg n, Reg t, Imm<12> imm12);
bool thumb32_STRT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_STR_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
// thumb32 load byte and memory hints
bool thumb32_PLD_lit(bool U, Imm<12> imm12);
bool thumb32_PLD_imm8(bool W, Reg n, Imm<8> imm8);
bool thumb32_PLD_imm12(bool W, Reg n, Imm<12> imm12);
bool thumb32_PLD_reg(bool W, Reg n, Imm<2> imm2, Reg m);
bool thumb32_PLI_lit(bool U, Imm<12> imm12);
bool thumb32_PLI_imm8(Reg n, Imm<8> imm8);
bool thumb32_PLI_imm12(Reg n, Imm<12> imm12);
bool thumb32_PLI_reg(Reg n, Imm<2> imm2, Reg m);
bool thumb32_LDRB_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRB_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRB_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRBT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDRSB_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRSB_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRSB_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRSB_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRSBT(Reg n, Reg t, Imm<8> imm8);
// thumb32 load halfword instructions
bool thumb32_LDRH_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRH_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRH_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRHT(Reg n, Reg t, Imm<8> imm8);
bool thumb32_LDRSH_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDRSH_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDRSH_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDRSH_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRSHT(Reg n, Reg t, Imm<8> imm8);
// thumb32 load word instructions
bool thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12);
bool thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m);
bool thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool W, Imm<8> imm8);
bool thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12);
bool thumb32_LDRT(Reg n, Reg t, Imm<8> imm8);
// thumb32 data processing (register) instructions
bool thumb32_ASR_reg(Reg m, Reg d, Reg s);
bool thumb32_LSL_reg(Reg m, Reg d, Reg s);
bool thumb32_LSR_reg(Reg m, Reg d, Reg s);
bool thumb32_ROR_reg(Reg m, Reg d, Reg s);
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTH(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTB16(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTAB16(Reg n, Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTH(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_UXTAH(Reg n, Reg d, SignExtendRotation rotate, Reg m);
// thumb32 long multiply, long multiply accumulate, and divide instructions
bool thumb32_SDIV(Reg n, Reg d, Reg m);
bool thumb32_SMLAL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_SMLALD(Reg n, Reg dLo, Reg dHi, bool M, Reg m);
bool thumb32_SMLALXY(Reg n, Reg dLo, Reg dHi, bool N, bool M, Reg m);
bool thumb32_SMLSLD(Reg n, Reg dLo, Reg dHi, bool M, Reg m);
bool thumb32_SMULL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_UDIV(Reg n, Reg d, Reg m);
bool thumb32_UMAAL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_UMLAL(Reg n, Reg dLo, Reg dHi, Reg m);
bool thumb32_UMULL(Reg n, Reg dLo, Reg dHi, Reg m);
// thumb32 miscellaneous instructions
bool thumb32_CLZ(Reg n, Reg d, Reg m);
bool thumb32_QADD(Reg n, Reg d, Reg m);
bool thumb32_QDADD(Reg n, Reg d, Reg m);
bool thumb32_QDSUB(Reg n, Reg d, Reg m);
bool thumb32_QSUB(Reg n, Reg d, Reg m);
bool thumb32_RBIT(Reg n, Reg d, Reg m);
bool thumb32_REV(Reg n, Reg d, Reg m);
bool thumb32_REV16(Reg n, Reg d, Reg m);
bool thumb32_REVSH(Reg n, Reg d, Reg m);
bool thumb32_SEL(Reg n, Reg d, Reg m);
// thumb32 multiply instructions
bool thumb32_MLA(Reg n, Reg a, Reg d, Reg m);
bool thumb32_MLS(Reg n, Reg a, Reg d, Reg m);
bool thumb32_MUL(Reg n, Reg d, Reg m);
bool thumb32_SMLAD(Reg n, Reg a, Reg d, bool X, Reg m);
bool thumb32_SMLAXY(Reg n, Reg a, Reg d, bool N, bool M, Reg m);
bool thumb32_SMLAWY(Reg n, Reg a, Reg d, bool M, Reg m);
bool thumb32_SMLSD(Reg n, Reg a, Reg d, bool X, Reg m);
bool thumb32_SMMLA(Reg n, Reg a, Reg d, bool R, Reg m);
bool thumb32_SMMLS(Reg n, Reg a, Reg d, bool R, Reg m);
bool thumb32_SMMUL(Reg n, Reg d, bool R, Reg m);
bool thumb32_SMUAD(Reg n, Reg d, bool M, Reg m);
bool thumb32_SMUSD(Reg n, Reg d, bool M, Reg m);
bool thumb32_SMULXY(Reg n, Reg d, bool N, bool M, Reg m);
bool thumb32_SMULWY(Reg n, Reg d, bool M, Reg m);
bool thumb32_USAD8(Reg n, Reg d, Reg m);
bool thumb32_USADA8(Reg n, Reg a, Reg d, Reg m);
// thumb32 parallel add/sub instructions
bool thumb32_SADD8(Reg n, Reg d, Reg m);
bool thumb32_SADD16(Reg n, Reg d, Reg m);
bool thumb32_SASX(Reg n, Reg d, Reg m);
bool thumb32_SSAX(Reg n, Reg d, Reg m);
bool thumb32_SSUB8(Reg n, Reg d, Reg m);
bool thumb32_SSUB16(Reg n, Reg d, Reg m);
bool thumb32_UADD8(Reg n, Reg d, Reg m);
bool thumb32_UADD16(Reg n, Reg d, Reg m);
bool thumb32_UASX(Reg n, Reg d, Reg m);
bool thumb32_USAX(Reg n, Reg d, Reg m);
bool thumb32_USUB8(Reg n, Reg d, Reg m);
bool thumb32_USUB16(Reg n, Reg d, Reg m);
bool thumb32_QADD8(Reg n, Reg d, Reg m);
bool thumb32_QADD16(Reg n, Reg d, Reg m);
bool thumb32_QASX(Reg n, Reg d, Reg m);
bool thumb32_QSAX(Reg n, Reg d, Reg m);
bool thumb32_QSUB8(Reg n, Reg d, Reg m);
bool thumb32_QSUB16(Reg n, Reg d, Reg m);
bool thumb32_UQADD8(Reg n, Reg d, Reg m);
bool thumb32_UQADD16(Reg n, Reg d, Reg m);
bool thumb32_UQASX(Reg n, Reg d, Reg m);
bool thumb32_UQSAX(Reg n, Reg d, Reg m);
bool thumb32_UQSUB8(Reg n, Reg d, Reg m);
bool thumb32_UQSUB16(Reg n, Reg d, Reg m);
bool thumb32_SHADD8(Reg n, Reg d, Reg m);
bool thumb32_SHADD16(Reg n, Reg d, Reg m);
bool thumb32_SHASX(Reg n, Reg d, Reg m);
bool thumb32_SHSAX(Reg n, Reg d, Reg m);
bool thumb32_SHSUB8(Reg n, Reg d, Reg m);
bool thumb32_SHSUB16(Reg n, Reg d, Reg m);
bool thumb32_UHADD8(Reg n, Reg d, Reg m);
bool thumb32_UHADD16(Reg n, Reg d, Reg m);
bool thumb32_UHASX(Reg n, Reg d, Reg m);
bool thumb32_UHSAX(Reg n, Reg d, Reg m);
bool thumb32_UHSUB8(Reg n, Reg d, Reg m);
bool thumb32_UHSUB16(Reg n, Reg d, Reg m);
};
} // namespace Dynarmic::A32

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
#include <array> #include <array>
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
template <typename FnT> template <typename FnT>
bool ArmTranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, ExtReg m, const FnT& fn) { bool TranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, ExtReg m, const FnT& fn) {
if (!ir.current_location.FPSCR().Stride()) { if (!ir.current_location.FPSCR().Stride()) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
@ -77,7 +77,7 @@ bool ArmTranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, E
} }
template <typename FnT> template <typename FnT>
bool ArmTranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg m, const FnT& fn) { bool TranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg m, const FnT& fn) {
return EmitVfpVectorOperation(sz, d, ExtReg::S0, m, [fn](ExtReg d, ExtReg, ExtReg m){ return EmitVfpVectorOperation(sz, d, ExtReg::S0, m, [fn](ExtReg d, ExtReg, ExtReg m){
fn(d, m); fn(d, m);
}); });
@ -85,8 +85,8 @@ bool ArmTranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg m, c
// VADD<c>.F64 <Dd>, <Dn>, <Dm> // VADD<c>.F64 <Dd>, <Dn>, <Dm>
// VADD<c>.F32 <Sd>, <Sn>, <Sm> // VADD<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -104,8 +104,8 @@ bool ArmTranslatorVisitor::vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VSUB<c>.F64 <Dd>, <Dn>, <Dm> // VSUB<c>.F64 <Dd>, <Dn>, <Dm>
// VSUB<c>.F32 <Sd>, <Sn>, <Sm> // VSUB<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -123,8 +123,8 @@ bool ArmTranslatorVisitor::vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VMUL<c>.F64 <Dd>, <Dn>, <Dm> // VMUL<c>.F64 <Dd>, <Dn>, <Dm>
// VMUL<c>.F32 <Sd>, <Sn>, <Sm> // VMUL<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -142,8 +142,8 @@ bool ArmTranslatorVisitor::vfp_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VMLA<c>.F64 <Dd>, <Dn>, <Dm> // VMLA<c>.F64 <Dd>, <Dn>, <Dm>
// VMLA<c>.F32 <Sd>, <Sn>, <Sm> // VMLA<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -162,8 +162,8 @@ bool ArmTranslatorVisitor::vfp_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VMLS<c>.F64 <Dd>, <Dn>, <Dm> // VMLS<c>.F64 <Dd>, <Dn>, <Dm>
// VMLS<c>.F32 <Sd>, <Sn>, <Sm> // VMLS<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -182,8 +182,8 @@ bool ArmTranslatorVisitor::vfp_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VNMUL<c>.F64 <Dd>, <Dn>, <Dm> // VNMUL<c>.F64 <Dd>, <Dn>, <Dm>
// VNMUL<c>.F32 <Sd>, <Sn>, <Sm> // VNMUL<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -201,8 +201,8 @@ bool ArmTranslatorVisitor::vfp_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, bo
// VNMLA<c>.F64 <Dd>, <Dn>, <Dm> // VNMLA<c>.F64 <Dd>, <Dn>, <Dm>
// VNMLA<c>.F32 <Sd>, <Sn>, <Sm> // VNMLA<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -221,8 +221,8 @@ bool ArmTranslatorVisitor::vfp_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, bo
// VNMLS<c>.F64 <Dd>, <Dn>, <Dm> // VNMLS<c>.F64 <Dd>, <Dn>, <Dm>
// VNMLS<c>.F32 <Sd>, <Sn>, <Sm> // VNMLS<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -241,8 +241,8 @@ bool ArmTranslatorVisitor::vfp_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, bo
// VDIV<c>.F64 <Dd>, <Dn>, <Dm> // VDIV<c>.F64 <Dd>, <Dn>, <Dm>
// VDIV<c>.F32 <Sd>, <Sn>, <Sm> // VDIV<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -260,8 +260,8 @@ bool ArmTranslatorVisitor::vfp_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VFNMS<c>.F64 <Dd>, <Dn>, <Dm> // VFNMS<c>.F64 <Dd>, <Dn>, <Dm>
// VFNMS<c>.F32 <Sd>, <Sn>, <Sm> // VFNMS<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFNMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VFNMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -280,8 +280,8 @@ bool ArmTranslatorVisitor::vfp_VFNMS(Cond cond, bool D, size_t Vn, size_t Vd, bo
// VFNMA<c>.F64 <Dd>, <Dn>, <Dm> // VFNMA<c>.F64 <Dd>, <Dn>, <Dm>
// VFNMA<c>.F32 <Sd>, <Sn>, <Sm> // VFNMA<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -300,8 +300,8 @@ bool ArmTranslatorVisitor::vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bo
// VFMA<c>.F64 <Dd>, <Dn>, <Dm> // VFMA<c>.F64 <Dd>, <Dn>, <Dm>
// VFMA<c>.F32 <Sd>, <Sn>, <Sm> // VFMA<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VFMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -320,8 +320,8 @@ bool ArmTranslatorVisitor::vfp_VFMA(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VFMS<c>.F64 <Dd>, <Dn>, <Dm> // VFMS<c>.F64 <Dd>, <Dn>, <Dm>
// VFMS<c>.F32 <Sd>, <Sn>, <Sm> // VFMS<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -340,7 +340,7 @@ bool ArmTranslatorVisitor::vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, boo
// VSEL<c>.F64 <Dd>, <Dn>, <Dm> // VSEL<c>.F64 <Dd>, <Dn>, <Dm>
// VSEL<c>.F32 <Sd>, <Sn>, <Sm> // VSEL<c>.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VSEL(bool D, Imm<2> cc, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VSEL(bool D, Imm<2> cc, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
const Cond cond = concatenate(cc, Imm<1>{cc.Bit<0>() != cc.Bit<1>()}, Imm<1>{0}).ZeroExtend<Cond>(); const Cond cond = concatenate(cc, Imm<1>{cc.Bit<0>() != cc.Bit<1>()}, Imm<1>{0}).ZeroExtend<Cond>();
const auto d = ToExtReg(sz, Vd, D); const auto d = ToExtReg(sz, Vd, D);
@ -357,7 +357,7 @@ bool ArmTranslatorVisitor::vfp_VSEL(bool D, Imm<2> cc, size_t Vn, size_t Vd, boo
// VMAXNM.F64 <Dd>, <Dn>, <Dm> // VMAXNM.F64 <Dd>, <Dn>, <Dm>
// VMAXNM.F32 <Sd>, <Sn>, <Sm> // VMAXNM.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VMAXNM(bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMAXNM(bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
const auto d = ToExtReg(sz, Vd, D); const auto d = ToExtReg(sz, Vd, D);
const auto n = ToExtReg(sz, Vn, N); const auto n = ToExtReg(sz, Vn, N);
const auto m = ToExtReg(sz, Vm, M); const auto m = ToExtReg(sz, Vm, M);
@ -372,7 +372,7 @@ bool ArmTranslatorVisitor::vfp_VMAXNM(bool D, size_t Vn, size_t Vd, bool sz, boo
// VMINNM.F64 <Dd>, <Dn>, <Dm> // VMINNM.F64 <Dd>, <Dn>, <Dm>
// VMINNM.F32 <Sd>, <Sn>, <Sm> // VMINNM.F32 <Sd>, <Sn>, <Sm>
bool ArmTranslatorVisitor::vfp_VMINNM(bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMINNM(bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
const auto d = ToExtReg(sz, Vd, D); const auto d = ToExtReg(sz, Vd, D);
const auto n = ToExtReg(sz, Vn, N); const auto n = ToExtReg(sz, Vn, N);
const auto m = ToExtReg(sz, Vm, M); const auto m = ToExtReg(sz, Vm, M);
@ -386,12 +386,12 @@ bool ArmTranslatorVisitor::vfp_VMINNM(bool D, size_t Vn, size_t Vd, bool sz, boo
} }
// VMOV<c>.32 <Dd[0]>, <Rt> // VMOV<c>.32 <Dd[0]>, <Rt>
bool ArmTranslatorVisitor::vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D) { bool TranslatorVisitor::vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -405,12 +405,12 @@ bool ArmTranslatorVisitor::vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D)
} }
// VMOV<c>.32 <Rt>, <Dn[0]> // VMOV<c>.32 <Rt>, <Dn[0]>
bool ArmTranslatorVisitor::vfp_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N) { bool TranslatorVisitor::vfp_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -421,12 +421,12 @@ bool ArmTranslatorVisitor::vfp_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N)
} }
// VMOV<c> <Sn>, <Rt> // VMOV<c> <Sn>, <Rt>
bool ArmTranslatorVisitor::vfp_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N) { bool TranslatorVisitor::vfp_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -436,12 +436,12 @@ bool ArmTranslatorVisitor::vfp_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N)
} }
// VMOV<c> <Rt>, <Sn> // VMOV<c> <Rt>, <Sn>
bool ArmTranslatorVisitor::vfp_VMOV_f32_u32(Cond cond, size_t Vn, Reg t, bool N) { bool TranslatorVisitor::vfp_VMOV_f32_u32(Cond cond, size_t Vn, Reg t, bool N) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -451,13 +451,13 @@ bool ArmTranslatorVisitor::vfp_VMOV_f32_u32(Cond cond, size_t Vn, Reg t, bool N)
} }
// VMOV<c> <Sm>, <Sm1>, <Rt>, <Rt2> // VMOV<c> <Sm>, <Sm1>, <Rt>, <Rt2>
bool ArmTranslatorVisitor::vfp_VMOV_2u32_2f32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMOV_2u32_2f32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
const auto m = ToExtReg(false, Vm, M); const auto m = ToExtReg(false, Vm, M);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) { if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -467,7 +467,7 @@ bool ArmTranslatorVisitor::vfp_VMOV_2u32_2f32(Cond cond, Reg t2, Reg t, bool M,
} }
// VMOV<c> <Rt>, <Rt2>, <Sm>, <Sm1> // VMOV<c> <Rt>, <Rt2>, <Sm>, <Sm1>
bool ArmTranslatorVisitor::vfp_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
const auto m = ToExtReg(false, Vm, M); const auto m = ToExtReg(false, Vm, M);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) { if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -477,7 +477,7 @@ bool ArmTranslatorVisitor::vfp_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M,
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -487,13 +487,13 @@ bool ArmTranslatorVisitor::vfp_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M,
} }
// VMOV<c> <Dm>, <Rt>, <Rt2> // VMOV<c> <Dm>, <Rt>, <Rt2>
bool ArmTranslatorVisitor::vfp_VMOV_2u32_f64(Cond cond, Reg t2, Reg t, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMOV_2u32_f64(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
const auto m = ToExtReg(true, Vm, M); const auto m = ToExtReg(true, Vm, M);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) { if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -503,7 +503,7 @@ bool ArmTranslatorVisitor::vfp_VMOV_2u32_f64(Cond cond, Reg t2, Reg t, bool M, s
} }
// VMOV<c> <Rt>, <Rt2>, <Dm> // VMOV<c> <Rt>, <Rt2>, <Dm>
bool ArmTranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm) {
const auto m = ToExtReg(true, Vm, M); const auto m = ToExtReg(true, Vm, M);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) { if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -513,7 +513,7 @@ bool ArmTranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, s
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -524,8 +524,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, s
} }
// VMOV<c>.32 <Dn[x]>, <Rt> // VMOV<c>.32 <Dn[x]>, <Rt>
bool ArmTranslatorVisitor::vfp_VMOV_from_i32(Cond cond, Imm<1> i, size_t Vd, Reg t, bool D) { bool TranslatorVisitor::vfp_VMOV_from_i32(Cond cond, Imm<1> i, size_t Vd, Reg t, bool D) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -546,8 +546,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_from_i32(Cond cond, Imm<1> i, size_t Vd, Reg
} }
// VMOV<c>.16 <Dn[x]>, <Rt> // VMOV<c>.16 <Dn[x]>, <Rt>
bool ArmTranslatorVisitor::vfp_VMOV_from_i16(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<1> i2) { bool TranslatorVisitor::vfp_VMOV_from_i16(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<1> i2) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -568,8 +568,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_from_i16(Cond cond, Imm<1> i1, size_t Vd, Re
} }
// VMOV<c>.8 <Dn[x]>, <Rt> // VMOV<c>.8 <Dn[x]>, <Rt>
bool ArmTranslatorVisitor::vfp_VMOV_from_i8(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<2> i2) { bool TranslatorVisitor::vfp_VMOV_from_i8(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<2> i2) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -590,8 +590,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_from_i8(Cond cond, Imm<1> i1, size_t Vd, Reg
} }
// VMOV<c>.32 <Rt>, <Dn[x]> // VMOV<c>.32 <Rt>, <Dn[x]>
bool ArmTranslatorVisitor::vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N) { bool TranslatorVisitor::vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -611,8 +611,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t
} }
// VMOV<c>.{U16,S16} <Rt>, <Dn[x]> // VMOV<c>.{U16,S16} <Rt>, <Dn[x]>
bool ArmTranslatorVisitor::vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2) { bool TranslatorVisitor::vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -633,8 +633,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t
} }
// VMOV<c>.{U8,S8} <Rt>, <Dn[x]> // VMOV<c>.{U8,S8} <Rt>, <Dn[x]>
bool ArmTranslatorVisitor::vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2) { bool TranslatorVisitor::vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -656,8 +656,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t V
// VDUP<c>.{8,16,32} <Qd>, <Rt> // VDUP<c>.{8,16,32} <Qd>, <Rt>
// VDUP<c>.{8,16,32} <Dd>, <Rt> // VDUP<c>.{8,16,32} <Dd>, <Rt>
bool ArmTranslatorVisitor::vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E) { bool TranslatorVisitor::vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -684,8 +684,8 @@ bool ArmTranslatorVisitor::vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg
// VMOV<c>.F64 <Dd>, #<imm> // VMOV<c>.F64 <Dd>, #<imm>
// VMOV<c>.F32 <Sd>, #<imm> // VMOV<c>.F32 <Sd>, #<imm>
bool ArmTranslatorVisitor::vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L) { bool TranslatorVisitor::vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -714,8 +714,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t
// VMOV<c>.F64 <Dd>, <Dm> // VMOV<c>.F64 <Dd>, <Dm>
// VMOV<c>.F32 <Sd>, <Sm> // VMOV<c>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -729,8 +729,8 @@ bool ArmTranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, b
// VABS<c>.F64 <Dd>, <Dm> // VABS<c>.F64 <Dd>, <Dm>
// VABS<c>.F32 <Sd>, <Sm> // VABS<c>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -746,8 +746,8 @@ bool ArmTranslatorVisitor::vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool
// VNEG<c>.F64 <Dd>, <Dm> // VNEG<c>.F64 <Dd>, <Dm>
// VNEG<c>.F32 <Sd>, <Sm> // VNEG<c>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -763,8 +763,8 @@ bool ArmTranslatorVisitor::vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool
// VSQRT<c>.F64 <Dd>, <Dm> // VSQRT<c>.F64 <Dd>, <Dm>
// VSQRT<c>.F32 <Sd>, <Sm> // VSQRT<c>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -782,8 +782,8 @@ bool ArmTranslatorVisitor::vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool
// VCVTB<c>.f64.f16 <Dd>, <Dm> // VCVTB<c>.f64.f16 <Dd>, <Dm>
// VCVTB<c>.f16.f32 <Dd>, <Dm> // VCVTB<c>.f16.f32 <Dd>, <Dm>
// VCVTB<c>.f16.f64 <Dd>, <Dm> // VCVTB<c>.f16.f64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -814,8 +814,8 @@ bool ArmTranslatorVisitor::vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool
// VCVTT<c>.f64.f16 <Dd>, <Dm> // VCVTT<c>.f64.f16 <Dd>, <Dm>
// VCVTT<c>.f16.f32 <Dd>, <Dm> // VCVTT<c>.f16.f32 <Dd>, <Dm>
// VCVTT<c>.f16.f64 <Dd>, <Dm> // VCVTT<c>.f16.f64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -844,8 +844,8 @@ bool ArmTranslatorVisitor::vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool
// VCMP{E}.F32 <Sd>, <Sm> // VCMP{E}.F32 <Sd>, <Sm>
// VCMP{E}.F64 <Dd>, <Dm> // VCMP{E}.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool E, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool E, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -862,8 +862,8 @@ bool ArmTranslatorVisitor::vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool
// VCMP{E}.F32 <Sd>, #0.0 // VCMP{E}.F32 <Sd>, #0.0
// VCMP{E}.F64 <Dd>, #0.0 // VCMP{E}.F64 <Dd>, #0.0
bool ArmTranslatorVisitor::vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, bool E) { bool TranslatorVisitor::vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, bool E) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -884,8 +884,8 @@ bool ArmTranslatorVisitor::vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz,
// VRINTR.{F16,F32} <Sd>, <Sm> // VRINTR.{F16,F32} <Sd>, <Sm>
// VRINTR.F64 <Dd>, <Dm> // VRINTR.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -901,8 +901,8 @@ bool ArmTranslatorVisitor::vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, boo
// VRINTZ.{F16,F32} <Sd>, <Sm> // VRINTZ.{F16,F32} <Sd>, <Sm>
// VRINTZ.F64 <Dd>, <Dm> // VRINTZ.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -918,8 +918,8 @@ bool ArmTranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, boo
// VRINTX.{F16,F32} <Sd>, <Sm> // VRINTX.{F16,F32} <Sd>, <Sm>
// VRINTX.F64 <Dd>, <Dm> // VRINTX.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTX(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VRINTX(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -935,8 +935,8 @@ bool ArmTranslatorVisitor::vfp_VRINTX(Cond cond, bool D, size_t Vd, bool sz, boo
// VCVT<c>.F64.F32 <Dd>, <Sm> // VCVT<c>.F64.F32 <Dd>, <Sm>
// VCVT<c>.F32.F64 <Sd>, <Dm> // VCVT<c>.F32.F64 <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -958,8 +958,8 @@ bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz
// VCVT.F32.{S32,U32} <Sd>, <Sm> // VCVT.F32.{S32,U32} <Sd>, <Sm>
// VCVT.F64.{S32,U32} <Sd>, <Dm> // VCVT.F64.{S32,U32} <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -985,8 +985,8 @@ bool ArmTranslatorVisitor::vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool
// VCVT.F32.{S16,U16,S32,U32} <Sdm>, <Sdm> // VCVT.F32.{S16,U16,S32,U32} <Sdm>, <Sdm>
// VCVT.F64.{S16,U16,S32,U32} <Ddm>, <Ddm> // VCVT.F64.{S16,U16,S32,U32} <Ddm>, <Ddm>
bool ArmTranslatorVisitor::vfp_VCVT_from_fixed(Cond cond, bool D, bool U, size_t Vd, bool sz, bool sx, Imm<1> i, Imm<4> imm4) { bool TranslatorVisitor::vfp_VCVT_from_fixed(Cond cond, bool D, bool U, size_t Vd, bool sz, bool sx, Imm<1> i, Imm<4> imm4) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1017,8 +1017,8 @@ bool ArmTranslatorVisitor::vfp_VCVT_from_fixed(Cond cond, bool D, bool U, size_t
// VCVT{,R}.U32.F32 <Sd>, <Sm> // VCVT{,R}.U32.F32 <Sd>, <Sm>
// VCVT{,R}.U32.F64 <Sd>, <Dm> // VCVT{,R}.U32.F64 <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1033,8 +1033,8 @@ bool ArmTranslatorVisitor::vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz
// VCVT{,R}.S32.F32 <Sd>, <Sm> // VCVT{,R}.S32.F32 <Sd>, <Sm>
// VCVT{,R}.S32.F64 <Sd>, <Dm> // VCVT{,R}.S32.F64 <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1049,8 +1049,8 @@ bool ArmTranslatorVisitor::vfp_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool sz
// VCVT.{S16,U16,S32,U32}.F32 <Sdm>, <Sdm> // VCVT.{S16,U16,S32,U32}.F32 <Sdm>, <Sdm>
// VCVT.{S16,U16,S32,U32}.F64 <Ddm>, <Ddm> // VCVT.{S16,U16,S32,U32}.F64 <Ddm>, <Ddm>
bool ArmTranslatorVisitor::vfp_VCVT_to_fixed(Cond cond, bool D, bool U, size_t Vd, bool sz, bool sx, Imm<1> i, Imm<4> imm4) { bool TranslatorVisitor::vfp_VCVT_to_fixed(Cond cond, bool D, bool U, size_t Vd, bool sz, bool sx, Imm<1> i, Imm<4> imm4) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1085,7 +1085,7 @@ bool ArmTranslatorVisitor::vfp_VCVT_to_fixed(Cond cond, bool D, bool U, size_t V
// VRINT{A,N,P,M}.F32 <Sd>, <Sm> // VRINT{A,N,P,M}.F32 <Sd>, <Sm>
// VRINT{A,N,P,M}.F64 <Dd>, <Dm> // VRINT{A,N,P,M}.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINT_rm(bool D, size_t rm, size_t Vd, bool sz, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VRINT_rm(bool D, size_t rm, size_t Vd, bool sz, bool M, size_t Vm) {
const std::array rm_lookup{ const std::array rm_lookup{
FP::RoundingMode::ToNearest_TieAwayFromZero, FP::RoundingMode::ToNearest_TieAwayFromZero,
FP::RoundingMode::ToNearest_TieEven, FP::RoundingMode::ToNearest_TieEven,
@ -1106,7 +1106,7 @@ bool ArmTranslatorVisitor::vfp_VRINT_rm(bool D, size_t rm, size_t Vd, bool sz, b
// VCVT{A,N,P,M}.F32 <Sd>, <Sm> // VCVT{A,N,P,M}.F32 <Sd>, <Sm>
// VCVT{A,N,P,M}.F64 <Sd>, <Dm> // VCVT{A,N,P,M}.F64 <Sd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCVT_rm(bool D, size_t rm, size_t Vd, bool sz, bool U, bool M, size_t Vm) { bool TranslatorVisitor::vfp_VCVT_rm(bool D, size_t rm, size_t Vd, bool sz, bool U, bool M, size_t Vm) {
const std::array rm_lookup{ const std::array rm_lookup{
FP::RoundingMode::ToNearest_TieAwayFromZero, FP::RoundingMode::ToNearest_TieAwayFromZero,
FP::RoundingMode::ToNearest_TieEven, FP::RoundingMode::ToNearest_TieEven,
@ -1127,12 +1127,12 @@ bool ArmTranslatorVisitor::vfp_VCVT_rm(bool D, size_t rm, size_t Vd, bool sz, bo
} }
// VMSR FPSCR, <Rt> // VMSR FPSCR, <Rt>
bool ArmTranslatorVisitor::vfp_VMSR(Cond cond, Reg t) { bool TranslatorVisitor::vfp_VMSR(Cond cond, Reg t) {
if (t == Reg::PC) { if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1146,8 +1146,8 @@ bool ArmTranslatorVisitor::vfp_VMSR(Cond cond, Reg t) {
} }
// VMRS <Rt>, FPSCR // VMRS <Rt>, FPSCR
bool ArmTranslatorVisitor::vfp_VMRS(Cond cond, Reg t) { bool TranslatorVisitor::vfp_VMRS(Cond cond, Reg t) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1163,7 +1163,7 @@ bool ArmTranslatorVisitor::vfp_VMRS(Cond cond, Reg t) {
} }
// VPOP.{F32,F64} <list> // VPOP.{F32,F64} <list>
bool ArmTranslatorVisitor::vfp_VPOP(Cond cond, bool D, size_t Vd, bool sz, Imm<8> imm8) { bool TranslatorVisitor::vfp_VPOP(Cond cond, bool D, size_t Vd, bool sz, Imm<8> imm8) {
const ExtReg d = ToExtReg(sz, Vd, D); const ExtReg d = ToExtReg(sz, Vd, D);
const size_t regs = sz ? imm8.ZeroExtend() >> 1 : imm8.ZeroExtend(); const size_t regs = sz ? imm8.ZeroExtend() >> 1 : imm8.ZeroExtend();
@ -1175,7 +1175,7 @@ bool ArmTranslatorVisitor::vfp_VPOP(Cond cond, bool D, size_t Vd, bool sz, Imm<8
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1204,7 +1204,7 @@ bool ArmTranslatorVisitor::vfp_VPOP(Cond cond, bool D, size_t Vd, bool sz, Imm<8
} }
// VPUSH.{F32,F64} <list> // VPUSH.{F32,F64} <list>
bool ArmTranslatorVisitor::vfp_VPUSH(Cond cond, bool D, size_t Vd, bool sz, Imm<8> imm8) { bool TranslatorVisitor::vfp_VPUSH(Cond cond, bool D, size_t Vd, bool sz, Imm<8> imm8) {
const ExtReg d = ToExtReg(sz, Vd, D); const ExtReg d = ToExtReg(sz, Vd, D);
const size_t regs = sz ? imm8.ZeroExtend() >> 1 : imm8.ZeroExtend(); const size_t regs = sz ? imm8.ZeroExtend() >> 1 : imm8.ZeroExtend();
@ -1216,7 +1216,7 @@ bool ArmTranslatorVisitor::vfp_VPUSH(Cond cond, bool D, size_t Vd, bool sz, Imm<
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1245,8 +1245,8 @@ bool ArmTranslatorVisitor::vfp_VPUSH(Cond cond, bool D, size_t Vd, bool sz, Imm<
// VLDR<c> <Dd>, [<Rn>{, #+/-<imm>}] // VLDR<c> <Dd>, [<Rn>{, #+/-<imm>}]
// VLDR<c> <Sd>, [<Rn>{, #+/-<imm>}] // VLDR<c> <Sd>, [<Rn>{, #+/-<imm>}]
bool ArmTranslatorVisitor::vfp_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) { bool TranslatorVisitor::vfp_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1271,8 +1271,8 @@ bool ArmTranslatorVisitor::vfp_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd,
// VSTR<c> <Dd>, [<Rn>{, #+/-<imm>}] // VSTR<c> <Dd>, [<Rn>{, #+/-<imm>}]
// VSTR<c> <Sd>, [<Rn>{, #+/-<imm>}] // VSTR<c> <Sd>, [<Rn>{, #+/-<imm>}]
bool ArmTranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) { bool TranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) {
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1297,7 +1297,7 @@ bool ArmTranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd,
} }
// VSTM{mode}<c> <Rn>{!}, <list of double registers> // VSTM{mode}<c> <Rn>{!}, <list of double registers>
bool ArmTranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) { bool TranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) { if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error"); ASSERT_MSG(false, "Decode error");
} }
@ -1321,7 +1321,7 @@ bool ArmTranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1349,7 +1349,7 @@ bool ArmTranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w
} }
// VSTM{mode}<c> <Rn>{!}, <list of single registers> // VSTM{mode}<c> <Rn>{!}, <list of single registers>
bool ArmTranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) { bool TranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) { if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error"); ASSERT_MSG(false, "Decode error");
} }
@ -1373,7 +1373,7 @@ bool ArmTranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1392,7 +1392,7 @@ bool ArmTranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w
} }
// VLDM{mode}<c> <Rn>{!}, <list of double registers> // VLDM{mode}<c> <Rn>{!}, <list of double registers>
bool ArmTranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) { bool TranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) { if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error"); ASSERT_MSG(false, "Decode error");
} }
@ -1416,7 +1416,7 @@ bool ArmTranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }
@ -1442,7 +1442,7 @@ bool ArmTranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w
} }
// VLDM{mode}<c> <Rn>{!}, <list of single registers> // VLDM{mode}<c> <Rn>{!}, <list of single registers>
bool ArmTranslatorVisitor::vfp_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) { bool TranslatorVisitor::vfp_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) { if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error"); ASSERT_MSG(false, "Decode error");
} }
@ -1466,7 +1466,7 @@ bool ArmTranslatorVisitor::vfp_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w
return UnpredictableInstruction(); return UnpredictableInstruction();
} }
if (!ConditionPassed(cond)) { if (!VFPConditionPassed(cond)) {
return true; return true;
} }

View file

@ -11,7 +11,7 @@
#include "frontend/A32/decoder/vfp.h" #include "frontend/A32/decoder/vfp.h"
#include "frontend/A32/location_descriptor.h" #include "frontend/A32/location_descriptor.h"
#include "frontend/A32/translate/conditional_state.h" #include "frontend/A32/translate/conditional_state.h"
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/translate.h" #include "frontend/A32/translate/translate.h"
#include "frontend/A32/types.h" #include "frontend/A32/types.h"
#include "ir/basic_block.h" #include "ir/basic_block.h"
@ -22,18 +22,19 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
const bool single_step = descriptor.SingleStepping(); const bool single_step = descriptor.SingleStepping();
IR::Block block{descriptor}; IR::Block block{descriptor};
ArmTranslatorVisitor visitor{block, descriptor, options}; TranslatorVisitor visitor{block, descriptor, options};
bool should_continue = true; bool should_continue = true;
do { do {
const u32 arm_pc = visitor.ir.current_location.PC(); const u32 arm_pc = visitor.ir.current_location.PC();
const u32 arm_instruction = memory_read_code(arm_pc); const u32 arm_instruction = memory_read_code(arm_pc);
visitor.current_instruction_size = 4;
if (const auto vfp_decoder = DecodeVFP<ArmTranslatorVisitor>(arm_instruction)) { if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(arm_instruction)) {
should_continue = vfp_decoder->get().call(visitor, arm_instruction); should_continue = vfp_decoder->get().call(visitor, arm_instruction);
} else if (const auto asimd_decoder = DecodeASIMD<ArmTranslatorVisitor>(arm_instruction)) { } else if (const auto asimd_decoder = DecodeASIMD<TranslatorVisitor>(arm_instruction)) {
should_continue = asimd_decoder->get().call(visitor, arm_instruction); should_continue = asimd_decoder->get().call(visitor, arm_instruction);
} else if (const auto decoder = DecodeArm<ArmTranslatorVisitor>(arm_instruction)) { } else if (const auto decoder = DecodeArm<TranslatorVisitor>(arm_instruction)) {
should_continue = decoder->get().call(visitor, arm_instruction); should_continue = decoder->get().call(visitor, arm_instruction);
} else { } else {
should_continue = visitor.arm_UDF(); should_continue = visitor.arm_UDF();
@ -65,16 +66,16 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
} }
bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 arm_instruction) { bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 arm_instruction) {
ArmTranslatorVisitor visitor{block, descriptor, {}}; TranslatorVisitor visitor{block, descriptor, {}};
// TODO: Proper cond handling // TODO: Proper cond handling
bool should_continue = true; bool should_continue = true;
if (const auto vfp_decoder = DecodeVFP<ArmTranslatorVisitor>(arm_instruction)) { if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(arm_instruction)) {
should_continue = vfp_decoder->get().call(visitor, arm_instruction); should_continue = vfp_decoder->get().call(visitor, arm_instruction);
} else if (const auto asimd_decoder = DecodeASIMD<ArmTranslatorVisitor>(arm_instruction)) { } else if (const auto asimd_decoder = DecodeASIMD<TranslatorVisitor>(arm_instruction)) {
should_continue = asimd_decoder->get().call(visitor, arm_instruction); should_continue = asimd_decoder->get().call(visitor, arm_instruction);
} else if (const auto decoder = DecodeArm<ArmTranslatorVisitor>(arm_instruction)) { } else if (const auto decoder = DecodeArm<TranslatorVisitor>(arm_instruction)) {
should_continue = decoder->get().call(visitor, arm_instruction); should_continue = decoder->get().call(visitor, arm_instruction);
} else { } else {
should_continue = visitor.arm_UDF(); should_continue = visitor.arm_UDF();
@ -90,88 +91,4 @@ bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descript
return should_continue; return should_continue;
} }
bool ArmTranslatorVisitor::ConditionPassed(Cond cond) {
return IsConditionPassed(cond, cond_state, ir, 4);
}
bool ArmTranslatorVisitor::InterpretThisInstruction() {
ir.SetTerm(IR::Term::Interpret(ir.current_location));
return false;
}
bool ArmTranslatorVisitor::UnpredictableInstruction() {
ir.ExceptionRaised(Exception::UnpredictableInstruction);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
bool ArmTranslatorVisitor::UndefinedInstruction() {
ir.ExceptionRaised(Exception::UndefinedInstruction);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
bool ArmTranslatorVisitor::DecodeError() {
ir.ExceptionRaised(Exception::DecodeError);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
bool ArmTranslatorVisitor::RaiseException(Exception exception) {
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
ir.ExceptionRaised(exception);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
IR::UAny ArmTranslatorVisitor::I(size_t bitsize, u64 value) {
switch (bitsize) {
case 8:
return ir.Imm8(static_cast<u8>(value));
case 16:
return ir.Imm16(static_cast<u16>(value));
case 32:
return ir.Imm32(static_cast<u32>(value));
case 64:
return ir.Imm64(value);
default:
ASSERT_FALSE("Imm - get: Invalid bitsize");
}
}
IR::ResultAndCarry<IR::U32> ArmTranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in) {
u8 imm5_value = imm5.ZeroExtend<u8>();
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::LSR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.LogicalShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ASR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.ArithmeticShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ROR:
if (imm5_value) {
return ir.RotateRight(value, ir.Imm8(imm5_value), carry_in);
} else {
return ir.RotateRightExtended(value, carry_in);
}
}
UNREACHABLE();
}
IR::ResultAndCarry<IR::U32> ArmTranslatorVisitor::EmitRegShift(IR::U32 value, ShiftType type, IR::U8 amount, IR::U1 carry_in) {
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, amount, carry_in);
case ShiftType::LSR:
return ir.LogicalShiftRight(value, amount, carry_in);
case ShiftType::ASR:
return ir.ArithmeticShiftRight(value, amount, carry_in);
case ShiftType::ROR:
return ir.RotateRight(value, amount, carry_in);
}
UNREACHABLE();
}
} // namespace Dynarmic::A32 } // namespace Dynarmic::A32

View file

@ -14,7 +14,7 @@
#include "frontend/A32/ir_emitter.h" #include "frontend/A32/ir_emitter.h"
#include "frontend/A32/location_descriptor.h" #include "frontend/A32/location_descriptor.h"
#include "frontend/A32/translate/conditional_state.h" #include "frontend/A32/translate/conditional_state.h"
#include "frontend/A32/translate/impl/translate_thumb.h" #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/translate.h" #include "frontend/A32/translate/translate.h"
#include "frontend/imm.h" #include "frontend/imm.h"
@ -69,23 +69,24 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
const bool single_step = descriptor.SingleStepping(); const bool single_step = descriptor.SingleStepping();
IR::Block block{descriptor}; IR::Block block{descriptor};
ThumbTranslatorVisitor visitor{block, descriptor, options}; TranslatorVisitor visitor{block, descriptor, options};
bool should_continue = true; bool should_continue = true;
do { do {
const u32 arm_pc = visitor.ir.current_location.PC(); const u32 arm_pc = visitor.ir.current_location.PC();
const auto [thumb_instruction, inst_size] = ReadThumbInstruction(arm_pc, memory_read_code); const auto [thumb_instruction, inst_size] = ReadThumbInstruction(arm_pc, memory_read_code);
const bool is_thumb_16 = inst_size == ThumbInstSize::Thumb16; const bool is_thumb_16 = inst_size == ThumbInstSize::Thumb16;
visitor.current_instruction_size = is_thumb_16 ? 2 : 4;
if (IsUnconditionalInstruction(is_thumb_16, thumb_instruction) || visitor.ConditionPassed(is_thumb_16)) { if (IsUnconditionalInstruction(is_thumb_16, thumb_instruction) || visitor.ThumbConditionPassed()) {
if (is_thumb_16) { if (is_thumb_16) {
if (const auto decoder = DecodeThumb16<ThumbTranslatorVisitor>(static_cast<u16>(thumb_instruction))) { if (const auto decoder = DecodeThumb16<TranslatorVisitor>(static_cast<u16>(thumb_instruction))) {
should_continue = decoder->get().call(visitor, static_cast<u16>(thumb_instruction)); should_continue = decoder->get().call(visitor, static_cast<u16>(thumb_instruction));
} else { } else {
should_continue = visitor.thumb16_UDF(); should_continue = visitor.thumb16_UDF();
} }
} else { } else {
if (const auto decoder = DecodeThumb32<ThumbTranslatorVisitor>(thumb_instruction)) { if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction); should_continue = decoder->get().call(visitor, thumb_instruction);
} else { } else {
should_continue = visitor.thumb32_UDF(); should_continue = visitor.thumb32_UDF();
@ -119,19 +120,19 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
} }
bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descriptor, u32 thumb_instruction) { bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descriptor, u32 thumb_instruction) {
ThumbTranslatorVisitor visitor{block, descriptor, {}}; TranslatorVisitor visitor{block, descriptor, {}};
const bool is_thumb_16 = IsThumb16(static_cast<u16>(thumb_instruction)); const bool is_thumb_16 = IsThumb16(static_cast<u16>(thumb_instruction));
bool should_continue = true; bool should_continue = true;
if (is_thumb_16) { if (is_thumb_16) {
if (const auto decoder = DecodeThumb16<ThumbTranslatorVisitor>(static_cast<u16>(thumb_instruction))) { if (const auto decoder = DecodeThumb16<TranslatorVisitor>(static_cast<u16>(thumb_instruction))) {
should_continue = decoder->get().call(visitor, static_cast<u16>(thumb_instruction)); should_continue = decoder->get().call(visitor, static_cast<u16>(thumb_instruction));
} else { } else {
should_continue = visitor.thumb16_UDF(); should_continue = visitor.thumb16_UDF();
} }
} else { } else {
thumb_instruction = Common::SwapHalves32(thumb_instruction); thumb_instruction = Common::SwapHalves32(thumb_instruction);
if (const auto decoder = DecodeThumb32<ThumbTranslatorVisitor>(thumb_instruction)) { if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction); should_continue = decoder->get().call(visitor, thumb_instruction);
} else { } else {
should_continue = visitor.thumb32_UDF(); should_continue = visitor.thumb32_UDF();
@ -147,54 +148,4 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri
return should_continue; return should_continue;
} }
bool ThumbTranslatorVisitor::ConditionPassed(bool is_thumb_16) {
const Cond cond = ir.current_location.IT().Cond();
return IsConditionPassed(cond, cond_state, ir, is_thumb_16 ? 2 : 4);
}
bool ThumbTranslatorVisitor::InterpretThisInstruction() {
ir.SetTerm(IR::Term::Interpret(ir.current_location));
return false;
}
bool ThumbTranslatorVisitor::UnpredictableInstruction() {
ir.ExceptionRaised(Exception::UnpredictableInstruction);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
bool ThumbTranslatorVisitor::UndefinedInstruction() {
ir.ExceptionRaised(Exception::UndefinedInstruction);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
bool ThumbTranslatorVisitor::RaiseException(Exception exception) {
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2)); // TODO: T32
ir.ExceptionRaised(exception);
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
return false;
}
IR::ResultAndCarry<IR::U32> ThumbTranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in) {
u8 imm5_value = imm5.ZeroExtend<u8>();
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::LSR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.LogicalShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ASR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.ArithmeticShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ROR:
if (imm5_value) {
return ir.RotateRight(value, ir.Imm8(imm5_value), carry_in);
} else {
return ir.RotateRightExtended(value, carry_in);
}
}
UNREACHABLE();
}
} // namespace Dynarmic::A32 } // namespace Dynarmic::A32

View file

@ -12,26 +12,26 @@
#include <dynarmic/A32/config.h> #include <dynarmic/A32/config.h>
#include "common/assert.h" #include "common/assert.h"
#include "frontend/A32/decoder/asimd.h" #include "frontend/A32/decoder/asimd.h"
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
#include "ir/opcodes.h" #include "ir/opcodes.h"
using namespace Dynarmic; using namespace Dynarmic;
TEST_CASE("ASIMD Decoder: Ensure table order correctness", "[decode][a32]") { TEST_CASE("ASIMD Decoder: Ensure table order correctness", "[decode][a32]") {
const auto table = A32::GetASIMDDecodeTable<A32::ArmTranslatorVisitor>(); const auto table = A32::GetASIMDDecodeTable<A32::TranslatorVisitor>();
const auto get_ir = [](const A32::ASIMDMatcher<A32::ArmTranslatorVisitor>& matcher, u32 instruction) { const auto get_ir = [](const A32::ASIMDMatcher<A32::TranslatorVisitor>& matcher, u32 instruction) {
ASSERT(matcher.Matches(instruction)); ASSERT(matcher.Matches(instruction));
const A32::LocationDescriptor location{0, {}, {}}; const A32::LocationDescriptor location{0, {}, {}};
IR::Block block{location}; IR::Block block{location};
A32::ArmTranslatorVisitor visitor{block, location, {}}; A32::TranslatorVisitor visitor{block, location, {}};
matcher.call(visitor, instruction); matcher.call(visitor, instruction);
return block; return block;
}; };
const auto is_decode_error = [&get_ir](const A32::ASIMDMatcher<A32::ArmTranslatorVisitor>& matcher, u32 instruction){ const auto is_decode_error = [&get_ir](const A32::ASIMDMatcher<A32::TranslatorVisitor>& matcher, u32 instruction){
const auto block = get_ir(matcher, instruction); const auto block = get_ir(matcher, instruction);
for (const auto& ir_inst : block) { for (const auto& ir_inst : block) {

View file

@ -21,7 +21,7 @@
#include "frontend/A32/decoder/asimd.h" #include "frontend/A32/decoder/asimd.h"
#include "frontend/A32/decoder/vfp.h" #include "frontend/A32/decoder/vfp.h"
#include "frontend/A32/location_descriptor.h" #include "frontend/A32/location_descriptor.h"
#include "frontend/A32/translate/impl/translate_arm.h" #include "frontend/A32/translate/impl/translate.h"
#include "frontend/A32/translate/translate.h" #include "frontend/A32/translate/translate.h"
#include "frontend/A64/decoder/a64.h" #include "frontend/A64/decoder/a64.h"
#include "frontend/A64/location_descriptor.h" #include "frontend/A64/location_descriptor.h"
@ -36,11 +36,11 @@
using namespace Dynarmic; using namespace Dynarmic;
const char* GetNameOfA32Instruction(u32 instruction) { const char* GetNameOfA32Instruction(u32 instruction) {
if (auto vfp_decoder = A32::DecodeVFP<A32::ArmTranslatorVisitor>(instruction)) { if (auto vfp_decoder = A32::DecodeVFP<A32::TranslatorVisitor>(instruction)) {
return vfp_decoder->get().GetName(); return vfp_decoder->get().GetName();
} else if (auto asimd_decoder = A32::DecodeASIMD<A32::ArmTranslatorVisitor>(instruction)) { } else if (auto asimd_decoder = A32::DecodeASIMD<A32::TranslatorVisitor>(instruction)) {
return asimd_decoder->get().GetName(); return asimd_decoder->get().GetName();
} else if (auto decoder = A32::DecodeArm<A32::ArmTranslatorVisitor>(instruction)) { } else if (auto decoder = A32::DecodeArm<A32::TranslatorVisitor>(instruction)) {
return decoder->get().GetName(); return decoder->get().GetName();
} }
return "<null>"; return "<null>";