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_parallel.cpp
frontend/A32/translate/impl/thumb32_store_single_data_item.cpp
frontend/A32/translate/impl/translate_arm.h
frontend/A32/translate/impl/translate_thumb.h
frontend/A32/translate/impl/translate.cpp
frontend/A32/translate/impl/translate.h
frontend/A32/translate/impl/vfp.cpp
frontend/A32/translate/translate.cpp
frontend/A32/translate/translate.h

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
#include <optional>
#include <tuple>
@ -72,7 +72,7 @@ std::optional<std::tuple<size_t, size_t, size_t>> DecodeType(Imm<4> type, size_t
}
} // 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) {
return DecodeError();
}
@ -121,7 +121,7 @@ bool ArmTranslatorVisitor::v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type
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) {
return DecodeError();
}
@ -178,7 +178,7 @@ bool ArmTranslatorVisitor::v8_VLD_multiple(bool D, Reg n, size_t Vd, Imm<4> type
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;
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;
}
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;
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;
}
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;
if (sz == 0b11) {

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
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 auto d = ToVector(false, Vd, D);
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;
}
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))) {
return UndefinedInstruction();
}
@ -57,15 +57,15 @@ bool ArmTranslatorVisitor::asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4,
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);
}
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);
}
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)) {
return UndefinedInstruction();
}

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
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) {
if (Q && Common::Bit<0>(Vd)) {
return UndefinedInstruction();

View file

@ -3,9 +3,9 @@
* 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 {
@ -28,7 +28,7 @@ enum class WidenBehaviour {
};
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))) {
return v.UndefinedInstruction();
}
@ -54,7 +54,7 @@ bool BitwiseInstruction(ArmTranslatorVisitor& v, bool D, size_t Vn, size_t Vd, b
}
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))) {
return v.UndefinedInstruction();
}
@ -76,7 +76,7 @@ bool FloatingPointInstruction(ArmTranslatorVisitor& v, bool D, bool sz, size_t V
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) {
if (sz == 0b11) {
return v.UndefinedInstruction();
@ -112,7 +112,7 @@ bool IntegerComparison(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_
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) {
if (sz) {
return v.UndefinedInstruction();
@ -149,7 +149,7 @@ bool FloatComparison(ArmTranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t
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) {
if (sz == 0b11) {
return v.UndefinedInstruction();
@ -182,7 +182,7 @@ bool AbsoluteDifference(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size
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) {
if (sz == 0b11) {
return v.DecodeError();
@ -218,7 +218,7 @@ bool AbsoluteDifferenceLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz,
}
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 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
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))) {
return UndefinedInstruction();
}
@ -271,7 +271,7 @@ bool ArmTranslatorVisitor::asimd_VHADD(bool U, bool D, size_t sz, size_t Vn, siz
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))) {
return UndefinedInstruction();
}
@ -293,7 +293,7 @@ bool ArmTranslatorVisitor::asimd_VQADD(bool U, bool D, size_t sz, size_t Vn, siz
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))) {
return UndefinedInstruction();
}
@ -315,55 +315,55 @@ bool ArmTranslatorVisitor::asimd_VRHADD(bool U, bool D, size_t sz, size_t Vn, si
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 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 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 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 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 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 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 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 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))) {
return UndefinedInstruction();
}
@ -385,7 +385,7 @@ bool ArmTranslatorVisitor::asimd_VHSUB(bool U, bool D, size_t sz, size_t Vn, siz
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))) {
return UndefinedInstruction();
}
@ -407,23 +407,23 @@ bool ArmTranslatorVisitor::asimd_VQSUB(bool U, bool D, size_t sz, size_t Vn, siz
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);
}
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);
}
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);
}
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);
}
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))) {
return UndefinedInstruction();
}
@ -441,7 +441,7 @@ bool ArmTranslatorVisitor::asimd_VADD_int(bool D, size_t sz, size_t Vn, size_t V
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))) {
return UndefinedInstruction();
}
@ -459,7 +459,7 @@ bool ArmTranslatorVisitor::asimd_VSUB_int(bool D, size_t sz, size_t Vn, size_t V
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))) {
return UndefinedInstruction();
}
@ -478,7 +478,7 @@ bool ArmTranslatorVisitor::asimd_VSHL_reg(bool U, bool D, size_t sz, size_t Vn,
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))) {
return UndefinedInstruction();
}
@ -497,7 +497,7 @@ bool ArmTranslatorVisitor::asimd_VQSHL_reg(bool U, bool D, size_t sz, size_t Vn,
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))) {
return UndefinedInstruction();
}
@ -516,7 +516,7 @@ bool ArmTranslatorVisitor::asimd_VRSHL(bool U, bool D, size_t sz, size_t Vn, siz
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) {
return UndefinedInstruction();
}
@ -546,7 +546,7 @@ bool ArmTranslatorVisitor::asimd_VMAX(bool U, bool D, size_t sz, size_t Vn, size
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))) {
return UndefinedInstruction();
}
@ -569,11 +569,11 @@ bool ArmTranslatorVisitor::asimd_VTST(bool D, size_t sz, size_t Vn, size_t Vd, b
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);
}
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) {
return UndefinedInstruction();
}
@ -598,7 +598,7 @@ bool ArmTranslatorVisitor::asimd_VMLA(bool op, bool D, size_t sz, size_t Vn, siz
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)) {
return UndefinedInstruction();
}
@ -621,7 +621,7 @@ bool ArmTranslatorVisitor::asimd_VMUL(bool P, bool D, size_t sz, size_t Vn, size
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) {
return UndefinedInstruction();
}
@ -651,7 +651,7 @@ bool ArmTranslatorVisitor::asimd_VPMAX_int(bool U, bool D, size_t sz, size_t Vn,
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))) {
return UndefinedInstruction();
}
@ -673,7 +673,7 @@ bool ArmTranslatorVisitor::asimd_VQDMULH(bool D, size_t sz, size_t Vn, size_t Vd
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))) {
return UndefinedInstruction();
}
@ -696,7 +696,7 @@ bool ArmTranslatorVisitor::asimd_VQRDMULH(bool D, size_t sz, size_t Vn, size_t V
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) {
return UndefinedInstruction();
}
@ -714,31 +714,31 @@ bool ArmTranslatorVisitor::asimd_VPADD(bool D, size_t sz, size_t Vn, size_t Vd,
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 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 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 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 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) {
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 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) {
const auto product = ir.FPVectorMul(32, reg_n, reg_m, 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) {
const auto product = ir.FPVectorMul(32, reg_n, reg_m, 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 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);
}
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);
}
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);
}
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;
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 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 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) {
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) {
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 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 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
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 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 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);
}
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);
}
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) {
const auto multiply = ir.VectorMultiply(esize, reg_n, reg_m);
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) {
return DecodeError();
}

View file

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

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include <utility>
#include "common/assert.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 {
namespace {
std::pair<ExtReg, size_t> GetScalarLocation(size_t esize, bool M, size_t Vm) {
@ -29,7 +29,7 @@ enum class Rounding {
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) {
if (sz == 0b11) {
return v.DecodeError();
@ -72,7 +72,8 @@ bool ScalarMultiply(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz, size_t V
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) {
return v.DecodeError();
}
@ -109,7 +110,7 @@ bool ScalarMultiplyLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size
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) {
if (sz == 0b11) {
return v.DecodeError();
@ -146,27 +147,27 @@ bool ScalarMultiplyReturnHigh(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz
}
} // 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
: MultiplyBehavior::MultiplyAccumulate;
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
: MultiplyBehavior::MultiplyAccumulate;
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);
}
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);
}
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) {
return DecodeError();
}
@ -189,11 +190,11 @@ bool ArmTranslatorVisitor::asimd_VQDMULL_scalar(bool D, size_t sz, size_t Vn, si
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);
}
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);
}

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 {
namespace {
enum class Accumulating {
@ -31,7 +31,7 @@ enum class Signedness {
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_correction = v.ir.VectorEqual(esize, v.ir.VectorAnd(original, round_const), round_const);
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) {
if (!L && Common::Bits<3, 5>(imm6) == 0) {
return v.DecodeError();
@ -89,7 +89,7 @@ bool ShiftRight(ArmTranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd,
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) {
if (Common::Bits<3, 5>(imm6) == 0) {
return v.DecodeError();
@ -140,27 +140,27 @@ bool ShiftRightNarrowing(ArmTranslatorVisitor& v, bool D, size_t imm6, size_t Vd
}
} // 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,
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,
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,
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,
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) {
return DecodeError();
}
@ -186,7 +186,7 @@ bool ArmTranslatorVisitor::asimd_VSRI(bool D, size_t imm6, size_t Vd, bool L, bo
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) {
return DecodeError();
}
@ -212,7 +212,7 @@ bool ArmTranslatorVisitor::asimd_VSLI(bool D, size_t imm6, size_t Vd, bool L, bo
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) {
return DecodeError();
}
@ -250,7 +250,7 @@ bool ArmTranslatorVisitor::asimd_VQSHL(bool U, bool D, size_t imm6, size_t Vd, b
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) {
return DecodeError();
}
@ -270,37 +270,37 @@ bool ArmTranslatorVisitor::asimd_VSHL(bool D, size_t imm6, size_t Vd, bool L, bo
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,
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,
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,
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,
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,
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,
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) {
return DecodeError();
}
@ -322,7 +322,7 @@ bool ArmTranslatorVisitor::asimd_VSHLL(bool U, bool D, size_t imm6, size_t Vd, b
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) {
return DecodeError();
}

View file

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

View file

@ -3,15 +3,15 @@
* 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 {
// B <label>
bool ArmTranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -22,8 +22,8 @@ bool ArmTranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) {
}
// BL <label>
bool ArmTranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -37,7 +37,7 @@ bool ArmTranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) {
}
// 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.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>
bool ArmTranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) {
bool TranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) {
if (m == Reg::PC) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -65,8 +65,8 @@ bool ArmTranslatorVisitor::arm_BLX_reg(Cond cond, Reg m) {
}
// BX <Rm>
bool ArmTranslatorVisitor::arm_BX(Cond cond, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_BX(Cond cond, Reg m) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -80,7 +80,7 @@ bool ArmTranslatorVisitor::arm_BX(Cond cond, Reg m) {
return false;
}
bool ArmTranslatorVisitor::arm_BXJ(Cond cond, Reg m) {
bool TranslatorVisitor::arm_BXJ(Cond cond, Reg m) {
// Jazelle not supported
return arm_BX(cond, m);
}

View file

@ -3,19 +3,19 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// 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) {
return arm_UDF();
}
const bool two = cond == Cond::NV;
if (two || ConditionPassed(cond)) {
if (two || ArmConditionPassed(cond)) {
ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2);
}
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>], <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) {
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;
if (two || ConditionPassed(cond)) {
if (two || ArmConditionPassed(cond)) {
const u32 imm32 = imm8.ZeroExtend() << 2;
const bool index = p;
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>
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) {
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;
if (two || ConditionPassed(cond)) {
if (two || ArmConditionPassed(cond)) {
ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t));
}
return true;
}
// 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) {
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;
if (two || ConditionPassed(cond)) {
if (two || ArmConditionPassed(cond)) {
ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2));
}
return true;
}
// 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) {
return arm_UDF();
}
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);
if (t != Reg::PC) {
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>
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) {
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;
if (two || ConditionPassed(cond)) {
if (two || ArmConditionPassed(cond)) {
const auto two_words = ir.CoprocGetTwoWords(coproc_no, two, opc, CRm);
ir.SetRegister(t, ir.LeastSignificantWord(two_words));
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>], <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) {
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;
if (two || ConditionPassed(cond)) {
if (two || ArmConditionPassed(cond)) {
const u32 imm32 = imm8.ZeroExtend() << 2;
const bool index = p;
const bool add = u;

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
@ -37,7 +37,7 @@ enum class CRCType {
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) {
return v.UnpredictableInstruction();
}
@ -83,12 +83,12 @@ bool CRC32Variant(ArmTranslatorVisitor& v, Cond cond, Imm<2> sz, Reg n, Reg d, R
} // Anonymous namespace
// 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);
}
// 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);
}

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// ADC{S}<c> <Rd>, <Rn>, #<imm>
bool ArmTranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_ADC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_ADD_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_ADD_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_AND_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_AND_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_BIC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_BIC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_CMN_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_CMN_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_CMN_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_CMN_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -400,8 +400,8 @@ bool ArmTranslatorVisitor::arm_CMN_rsr(Cond cond, Reg n, Reg s, ShiftType shift,
}
// CMP<c> <Rn>, #<imm>
bool ArmTranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_CMP_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_CMP_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_EOR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_EOR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_MOV_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -596,12 +596,12 @@ bool ArmTranslatorVisitor::arm_MOV_reg(Cond cond, bool S, Reg d, Imm<5> imm5, Sh
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_MVN_imm(Cond cond, bool S, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_MVN_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_MVN_reg(Cond cond, bool S, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_ORR_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_ORR_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_RSB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_RSB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -903,8 +903,8 @@ bool ArmTranslatorVisitor::arm_RSC_imm(Cond cond, bool S, Reg n, Reg d, int rota
return true;
}
bool ArmTranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_RSC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>}
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_SBC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_SBC_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_SUB_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -1104,12 +1104,12 @@ bool ArmTranslatorVisitor::arm_SUB_reg(Cond cond, bool S, Reg n, Reg d, Imm<5> i
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_TEQ_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_TEQ_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_TEQ_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -1182,8 +1182,8 @@ bool ArmTranslatorVisitor::arm_TEQ_rsr(Cond cond, Reg n, Reg s, ShiftType shift,
}
// TST<c> <Rn>, #<const>
bool ArmTranslatorVisitor::arm_TST_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_TST_imm(Cond cond, Reg n, int rotate, Imm<8> imm8) {
if (!ArmConditionPassed(cond)) {
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>}
bool ArmTranslatorVisitor::arm_TST_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_TST_reg(Cond cond, Reg n, Imm<5> imm5, ShiftType shift, Reg m) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,19 +3,19 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
namespace {
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) {
if (d == Reg::PC || m == Reg::PC || n == Reg::PC) {
return v.UnpredictableInstruction();
}
if (!v.ConditionPassed(cond)) {
if (!v.ArmConditionPassed(cond)) {
return true;
}
@ -29,12 +29,12 @@ bool DivideOperation(ArmTranslatorVisitor& v, Cond cond, Reg d, Reg m, Reg n,
} // Anonymous namespace
// 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);
}
// 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);
}

View file

@ -3,20 +3,20 @@
* 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 {
// 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) {
return UnpredictableInstruction();
}
// UNPREDICTABLE: The instruction executes conditionally.
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -26,8 +26,8 @@ bool ArmTranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*
}
// SVC<c> #<imm24>
bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm<24> imm24) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_SVC(Cond cond, Imm<24> imm24) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -40,7 +40,7 @@ bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm<24> imm24) {
}
// UDF<c> #<imm16>
bool ArmTranslatorVisitor::arm_UDF() {
bool TranslatorVisitor::arm_UDF() {
return UndefinedInstruction();
}

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
@ -13,12 +13,12 @@ static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -31,12 +31,12 @@ bool ArmTranslatorVisitor::arm_SXTAB(Cond cond, Reg n, Reg d, SignExtendRotation
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -51,12 +51,12 @@ bool ArmTranslatorVisitor::arm_SXTAB16(Cond cond, Reg n, Reg d, SignExtendRotati
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -69,12 +69,12 @@ bool ArmTranslatorVisitor::arm_SXTAH(Cond cond, Reg n, Reg d, SignExtendRotation
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -86,12 +86,12 @@ bool ArmTranslatorVisitor::arm_SXTB(Cond cond, Reg d, SignExtendRotation rotate,
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -105,12 +105,12 @@ bool ArmTranslatorVisitor::arm_SXTB16(Cond cond, Reg d, SignExtendRotation rotat
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -122,12 +122,12 @@ bool ArmTranslatorVisitor::arm_SXTH(Cond cond, Reg d, SignExtendRotation rotate,
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -140,12 +140,12 @@ bool ArmTranslatorVisitor::arm_UXTAB(Cond cond, Reg n, Reg d, SignExtendRotation
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -159,12 +159,12 @@ bool ArmTranslatorVisitor::arm_UXTAB16(Cond cond, Reg n, Reg d, SignExtendRotati
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -177,12 +177,12 @@ bool ArmTranslatorVisitor::arm_UXTAH(Cond cond, Reg n, Reg d, SignExtendRotation
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -193,12 +193,12 @@ bool ArmTranslatorVisitor::arm_UXTB(Cond cond, Reg d, SignExtendRotation rotate,
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -210,12 +210,12 @@ bool ArmTranslatorVisitor::arm_UXTB16(Cond cond, Reg d, SignExtendRotation rotat
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

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

View file

@ -3,46 +3,46 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
bool ArmTranslatorVisitor::arm_LDRBT() {
bool TranslatorVisitor::arm_LDRBT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_LDRHT() {
bool TranslatorVisitor::arm_LDRHT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_LDRSBT() {
bool TranslatorVisitor::arm_LDRSBT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_LDRSHT() {
bool TranslatorVisitor::arm_LDRSHT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_LDRT() {
bool TranslatorVisitor::arm_LDRT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_STRBT() {
bool TranslatorVisitor::arm_STRBT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_STRHT() {
bool TranslatorVisitor::arm_STRHT() {
// System instructions unimplemented
return UndefinedInstruction();
}
bool ArmTranslatorVisitor::arm_STRT() {
bool TranslatorVisitor::arm_STRT() {
// System instructions unimplemented
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>]
bool ArmTranslatorVisitor::arm_LDR_lit(Cond cond, bool U, Reg t, Imm<12> imm12) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::arm_LDR_lit(Cond cond, bool U, Reg t, Imm<12> imm12) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -95,7 +95,7 @@ bool ArmTranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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");
if (m == Reg::PC) {
return UnpredictableInstruction();
@ -132,7 +132,7 @@ bool ArmTranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>]
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -186,7 +186,7 @@ bool ArmTranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -211,7 +211,7 @@ bool ArmTranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>]
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) {
return UnpredictableInstruction();
}
@ -233,7 +233,7 @@ bool ArmTranslatorVisitor::arm_LDRD_lit(Cond cond, bool U, Reg t, Imm<4> imm8a,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -274,7 +274,7 @@ bool ArmTranslatorVisitor::arm_LDRD_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -311,7 +311,7 @@ bool ArmTranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>]
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");
if (P == W) {
return UnpredictableInstruction();
@ -338,7 +338,7 @@ bool ArmTranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -368,7 +368,7 @@ bool ArmTranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -393,7 +393,7 @@ bool ArmTranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>]
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -442,7 +442,7 @@ bool ArmTranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -467,7 +467,7 @@ bool ArmTranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -480,12 +480,12 @@ bool ArmTranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -515,7 +515,7 @@ bool ArmTranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -540,7 +540,7 @@ bool ArmTranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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)) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -580,7 +580,7 @@ bool ArmTranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -601,7 +601,7 @@ bool ArmTranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -622,7 +622,7 @@ bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -652,7 +652,7 @@ bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -688,7 +688,7 @@ bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -714,7 +714,7 @@ bool ArmTranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -737,7 +737,7 @@ bool ArmTranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -779,7 +779,7 @@ bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -789,7 +789,7 @@ bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList 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) {
return UnpredictableInstruction();
}
@ -797,7 +797,7 @@ bool ArmTranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -807,7 +807,7 @@ bool ArmTranslatorVisitor::arm_LDMDA(Cond cond, bool W, Reg n, RegList 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) {
return UnpredictableInstruction();
}
@ -815,7 +815,7 @@ bool ArmTranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -825,7 +825,7 @@ bool ArmTranslatorVisitor::arm_LDMDB(Cond cond, bool W, Reg n, RegList 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) {
return UnpredictableInstruction();
}
@ -833,7 +833,7 @@ bool ArmTranslatorVisitor::arm_LDMIB(Cond cond, bool W, Reg n, RegList list) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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);
}
bool ArmTranslatorVisitor::arm_LDM_usr() {
bool TranslatorVisitor::arm_LDM_usr() {
return InterpretThisInstruction();
}
bool ArmTranslatorVisitor::arm_LDM_eret() {
bool TranslatorVisitor::arm_LDM_eret() {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -883,12 +883,12 @@ bool ArmTranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -898,12 +898,12 @@ bool ArmTranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -913,12 +913,12 @@ bool ArmTranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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);
}
bool ArmTranslatorVisitor::arm_STM_usr() {
bool TranslatorVisitor::arm_STM_usr() {
return InterpretThisInstruction();
}

View file

@ -3,13 +3,14 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 {
// 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) {
return UnpredictableInstruction();
}
@ -17,7 +18,7 @@ bool ArmTranslatorVisitor::arm_BFC(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -40,7 +41,7 @@ bool ArmTranslatorVisitor::arm_BFI(Cond cond, Imm<5> msb, Reg d, Imm<5> lsb, Reg
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -71,12 +72,12 @@ bool ArmTranslatorVisitor::arm_CLZ(Cond cond, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -88,12 +89,12 @@ bool ArmTranslatorVisitor::arm_MOVT(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -116,7 +117,7 @@ bool ArmTranslatorVisitor::arm_SBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -151,7 +152,7 @@ bool ArmTranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
@ -163,7 +164,7 @@ bool ArmTranslatorVisitor::arm_UBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -77,7 +77,7 @@ bool ArmTranslatorVisitor::arm_SMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -109,7 +109,7 @@ bool ArmTranslatorVisitor::arm_SMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -139,7 +139,7 @@ bool ArmTranslatorVisitor::arm_UMAAL(Cond cond, Reg dHi, Reg dLo, Reg m, Reg n)
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -164,7 +164,7 @@ bool ArmTranslatorVisitor::arm_UMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -195,7 +195,7 @@ bool ArmTranslatorVisitor::arm_UMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -225,7 +225,7 @@ bool ArmTranslatorVisitor::arm_SMLALxy(Cond cond, Reg dHi, Reg dLo, Reg m, bool
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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 */) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
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();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -454,7 +454,7 @@ bool ArmTranslatorVisitor::arm_SMLALD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
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();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -525,7 +525,7 @@ bool ArmTranslatorVisitor::arm_SMLSLD(Cond cond, Reg dHi, Reg dLo, Reg m, bool M
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>}
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -24,12 +24,12 @@ bool ArmTranslatorVisitor::arm_SADD8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -40,12 +40,12 @@ bool ArmTranslatorVisitor::arm_SADD16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -56,12 +56,12 @@ bool ArmTranslatorVisitor::arm_SASX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -72,12 +72,12 @@ bool ArmTranslatorVisitor::arm_SSAX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -88,12 +88,12 @@ bool ArmTranslatorVisitor::arm_SSUB8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -104,12 +104,12 @@ bool ArmTranslatorVisitor::arm_SSUB16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -120,12 +120,12 @@ bool ArmTranslatorVisitor::arm_UADD8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -136,12 +136,12 @@ bool ArmTranslatorVisitor::arm_UADD16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -152,12 +152,12 @@ bool ArmTranslatorVisitor::arm_UASX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -168,12 +168,12 @@ bool ArmTranslatorVisitor::arm_USAX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -183,12 +183,12 @@ bool ArmTranslatorVisitor::arm_USAD8(Cond cond, Reg d, Reg m, Reg n) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -215,12 +215,12 @@ bool ArmTranslatorVisitor::arm_USUB8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -233,12 +233,12 @@ bool ArmTranslatorVisitor::arm_USUB16(Cond cond, Reg n, Reg d, Reg m) {
// Parallel Add/Subtract (Saturating) instructions
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -248,12 +248,12 @@ bool ArmTranslatorVisitor::arm_QADD8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -263,12 +263,12 @@ bool ArmTranslatorVisitor::arm_QADD16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -278,12 +278,12 @@ bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -293,12 +293,12 @@ bool ArmTranslatorVisitor::arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -308,12 +308,12 @@ bool ArmTranslatorVisitor::arm_UQADD8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -323,12 +323,12 @@ bool ArmTranslatorVisitor::arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -338,12 +338,12 @@ bool ArmTranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -355,12 +355,12 @@ bool ArmTranslatorVisitor::arm_UQSUB16(Cond cond, Reg n, Reg d, Reg m) {
// Parallel Add/Subtract (Halving) instructions
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -370,12 +370,12 @@ bool ArmTranslatorVisitor::arm_SHADD8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -385,12 +385,12 @@ bool ArmTranslatorVisitor::arm_SHADD16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -400,12 +400,12 @@ bool ArmTranslatorVisitor::arm_SHASX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -415,12 +415,12 @@ bool ArmTranslatorVisitor::arm_SHSAX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -430,12 +430,12 @@ bool ArmTranslatorVisitor::arm_SHSUB8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -445,12 +445,12 @@ bool ArmTranslatorVisitor::arm_SHSUB16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -460,12 +460,12 @@ bool ArmTranslatorVisitor::arm_UHADD8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -475,12 +475,12 @@ bool ArmTranslatorVisitor::arm_UHADD16(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -490,12 +490,12 @@ bool ArmTranslatorVisitor::arm_UHASX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -505,12 +505,12 @@ bool ArmTranslatorVisitor::arm_UHSAX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -520,12 +520,12 @@ bool ArmTranslatorVisitor::arm_UHSUB8(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,17 +3,17 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -38,12 +38,12 @@ bool ArmTranslatorVisitor::arm_RBIT(Cond cond, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -53,12 +53,12 @@ bool ArmTranslatorVisitor::arm_REV(Cond cond, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -72,12 +72,12 @@ bool ArmTranslatorVisitor::arm_REV16(Cond cond, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
@ -18,12 +18,12 @@ static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
// Saturation instructions
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>}
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -105,12 +105,12 @@ bool ArmTranslatorVisitor::arm_USAT16(Cond cond, Imm<4> sat_imm, Reg d, Reg n) {
// Saturated Add/Subtract instructions
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -124,12 +124,12 @@ bool ArmTranslatorVisitor::arm_QADD(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -143,12 +143,12 @@ bool ArmTranslatorVisitor::arm_QSUB(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -164,12 +164,12 @@ bool ArmTranslatorVisitor::arm_QDADD(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -187,12 +187,12 @@ bool ArmTranslatorVisitor::arm_QDSUB(Cond cond, Reg n, Reg d, Reg m) {
// Parallel saturated instructions
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -211,12 +211,12 @@ bool ArmTranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -235,12 +235,12 @@ bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -259,12 +259,12 @@ bool ArmTranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,24 +3,25 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_arm.h"
namespace Dynarmic::A32 {
// CPS<effect> <iflags>{, #<mode>}
// CPS #<mode>
bool ArmTranslatorVisitor::arm_CPS() {
bool TranslatorVisitor::arm_CPS() {
return InterpretThisInstruction();
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -29,10 +30,10 @@ bool ArmTranslatorVisitor::arm_MRS(Cond cond, Reg d) {
}
// 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");
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
@ -70,7 +71,7 @@ bool ArmTranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -102,18 +103,18 @@ bool ArmTranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) {
}
// RFE{<amode>} <Rn>{!}
bool ArmTranslatorVisitor::arm_RFE() {
bool TranslatorVisitor::arm_RFE() {
return InterpretThisInstruction();
}
// 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)});
return false;
}
// SRS{<amode>} SP{!}, #<mode>
bool ArmTranslatorVisitor::arm_SRS() {
bool TranslatorVisitor::arm_SRS() {
return InterpretThisInstruction();
}

View file

@ -3,24 +3,24 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// CLREX
bool ArmTranslatorVisitor::arm_CLREX() {
bool TranslatorVisitor::arm_CLREX() {
ir.ClearExclusive();
return true;
}
// SWP<c> <Rt>, <Rt2>, [<Rn>]
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -33,12 +33,12 @@ bool ArmTranslatorVisitor::arm_SWP(Cond cond, Reg n, Reg t, Reg t2) {
// SWPB<c> <Rt>, <Rt2>, [<Rn>]
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -50,12 +50,12 @@ bool ArmTranslatorVisitor::arm_SWPB(Cond cond, Reg n, Reg t, Reg t2) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -64,12 +64,12 @@ bool ArmTranslatorVisitor::arm_LDA(Cond cond, Reg n, Reg t) {
return true;
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -78,12 +78,12 @@ bool ArmTranslatorVisitor::arm_LDAB(Cond cond, Reg n, Reg t) {
return true;
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -93,12 +93,12 @@ bool ArmTranslatorVisitor::arm_LDAH(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -108,12 +108,12 @@ bool ArmTranslatorVisitor::arm_LDAEX(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -123,12 +123,12 @@ bool ArmTranslatorVisitor::arm_LDAEXB(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -141,12 +141,12 @@ bool ArmTranslatorVisitor::arm_LDAEXD(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -156,12 +156,12 @@ bool ArmTranslatorVisitor::arm_LDAEXH(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -171,12 +171,12 @@ bool ArmTranslatorVisitor::arm_STL(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -186,12 +186,12 @@ bool ArmTranslatorVisitor::arm_STLB(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -201,7 +201,7 @@ bool ArmTranslatorVisitor::arm_STLH(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -210,7 +210,7 @@ bool ArmTranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -221,7 +221,7 @@ bool ArmTranslatorVisitor::arm_STLEXB(Cond cond, Reg n, Reg d, Reg t) {
return true;
}
// 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) {
return UnpredictableInstruction();
}
@ -230,7 +230,7 @@ bool ArmTranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -244,7 +244,7 @@ bool ArmTranslatorVisitor::arm_STLEXD(Cond cond, Reg n, Reg d, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -253,7 +253,7 @@ bool ArmTranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -265,7 +265,7 @@ bool ArmTranslatorVisitor::arm_STLEXH(Cond cond, Reg n, Reg d, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -274,7 +274,7 @@ bool ArmTranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -286,12 +286,12 @@ bool ArmTranslatorVisitor::arm_STLEX(Cond cond, Reg n, Reg d, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -301,12 +301,12 @@ bool ArmTranslatorVisitor::arm_LDREX(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -316,12 +316,12 @@ bool ArmTranslatorVisitor::arm_LDREXB(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -334,12 +334,12 @@ bool ArmTranslatorVisitor::arm_LDREXD(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -349,7 +349,7 @@ bool ArmTranslatorVisitor::arm_LDREXH(Cond cond, Reg n, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -358,7 +358,7 @@ bool ArmTranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -370,7 +370,7 @@ bool ArmTranslatorVisitor::arm_STREX(Cond cond, Reg n, Reg d, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -379,7 +379,7 @@ bool ArmTranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -391,7 +391,7 @@ bool ArmTranslatorVisitor::arm_STREXB(Cond cond, Reg n, Reg d, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -400,7 +400,7 @@ bool ArmTranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}
@ -414,7 +414,7 @@ bool ArmTranslatorVisitor::arm_STREXD(Cond cond, Reg n, Reg d, Reg t) {
}
// 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) {
return UnpredictableInstruction();
}
@ -423,7 +423,7 @@ bool ArmTranslatorVisitor::arm_STREXH(Cond cond, Reg n, Reg d, Reg t) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!ArmConditionPassed(cond)) {
return true;
}

View file

@ -3,14 +3,14 @@
* 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 {
// 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>();
if (shift_n == 0 && ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction();
@ -29,7 +29,7 @@ bool ThumbTranslatorVisitor::thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d) {
}
// 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 auto cpsr_c = ir.GetCFlag();
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>
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 auto cpsr_c = ir.GetCFlag();
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>
// 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));
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>
// 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));
ir.SetRegister(d, result.result);
@ -90,7 +90,7 @@ bool ThumbTranslatorVisitor::thumb16_SUB_reg(Reg m, Reg n, Reg d) {
// ADDS <Rd>, <Rn>, #<imm3>
// 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 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>
// 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 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>
// 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 auto result = ir.Imm32(imm32);
@ -135,7 +135,7 @@ bool ThumbTranslatorVisitor::thumb16_MOV_imm(Reg d, Imm<8> 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 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>
// 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 Reg d = 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>
// 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 Reg d = 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>
// 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 n = d_n;
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>
// 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 n = d_n;
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>
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 n = d_n;
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>
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 n = d_n;
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>
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 n = d_n;
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>
// 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 n = d_n;
const auto aspr_c = ir.GetCFlag();
@ -283,7 +283,7 @@ bool ThumbTranslatorVisitor::thumb16_ADC_reg(Reg m, Reg d_n) {
// SBCS <Rdn>, <Rm>
// 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 n = d_n;
const auto aspr_c = ir.GetCFlag();
@ -300,7 +300,7 @@ bool ThumbTranslatorVisitor::thumb16_SBC_reg(Reg m, Reg d_n) {
}
// 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 n = d_n;
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>
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));
ir.SetNFlag(ir.MostSignificantBit(result));
ir.SetZFlag(ir.IsZero(result));
@ -326,7 +326,7 @@ bool ThumbTranslatorVisitor::thumb16_TST_reg(Reg m, Reg n) {
// RSBS <Rd>, <Rn>, #0
// 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));
ir.SetRegister(d, result.result);
if (!ir.current_location.IT().IsInITBlock()) {
@ -339,7 +339,7 @@ bool ThumbTranslatorVisitor::thumb16_RSB_imm(Reg n, Reg d) {
}
// 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));
ir.SetNFlag(ir.MostSignificantBit(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>
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));
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
@ -360,7 +360,7 @@ bool ThumbTranslatorVisitor::thumb16_CMN_reg(Reg m, Reg n) {
// ORRS <Rdn>, <Rm>
// 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 n = d_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>
// 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 m = d_m;
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>
// 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 n = d_n;
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>
// 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));
ir.SetRegister(d, result);
@ -417,7 +417,7 @@ bool ThumbTranslatorVisitor::thumb16_MVN_reg(Reg m, Reg d) {
}
// 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 n = 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>
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;
if (n < Reg::R8 && m < Reg::R8) {
return UnpredictableInstruction();
@ -460,7 +460,7 @@ bool ThumbTranslatorVisitor::thumb16_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) {
}
// 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;
if (d == Reg::PC && ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock()) {
return UnpredictableInstruction();
@ -481,7 +481,7 @@ bool ThumbTranslatorVisitor::thumb16_MOV_reg(bool d_hi, Reg m, Reg d_lo) {
// LDR <Rt>, <label>
// 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 address = ir.AlignPC(4) + imm32;
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>]
// 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 data = ir.GetRegister(t);
@ -502,7 +502,7 @@ bool ThumbTranslatorVisitor::thumb16_STR_reg(Reg m, Reg n, Reg t) {
// STRH <Rt>, [<Rn>, <Rm>]
// 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 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>]
// 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 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>]
// 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 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>]
// 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 data = ir.ReadMemory32(address);
@ -542,7 +542,7 @@ bool ThumbTranslatorVisitor::thumb16_LDR_reg(Reg m, Reg n, Reg t) {
// LDRH <Rt>, [<Rn>, <Rm>]
// 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 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>]
// 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 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>]
// 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 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>]
// 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 auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
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>]
// 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 auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
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>]
// 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 auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
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>]
// 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 auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
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>]
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 auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
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>]
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 auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
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>]
// 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 Reg n = Reg::SP;
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>]
// 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 Reg n = Reg::SP;
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>
// 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 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>
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 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>
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 Reg d = Reg::SP;
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>
bool ThumbTranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
const u32 imm32 = imm7.ZeroExtend() << 2;
const Reg d = Reg::SP;
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>
bool ThumbTranslatorVisitor::thumb16_SEV() {
bool TranslatorVisitor::thumb16_SEV() {
if (!options.hook_hint_instructions) {
return true;
}
@ -706,7 +706,7 @@ bool ThumbTranslatorVisitor::thumb16_SEV() {
}
// SEVL<c>
bool ThumbTranslatorVisitor::thumb16_SEVL() {
bool TranslatorVisitor::thumb16_SEVL() {
if (!options.hook_hint_instructions) {
return true;
}
@ -714,7 +714,7 @@ bool ThumbTranslatorVisitor::thumb16_SEVL() {
}
// WFE<c>
bool ThumbTranslatorVisitor::thumb16_WFE() {
bool TranslatorVisitor::thumb16_WFE() {
if (!options.hook_hint_instructions) {
return true;
}
@ -722,7 +722,7 @@ bool ThumbTranslatorVisitor::thumb16_WFE() {
}
// WFI<c>
bool ThumbTranslatorVisitor::thumb16_WFI() {
bool TranslatorVisitor::thumb16_WFI() {
if (!options.hook_hint_instructions) {
return true;
}
@ -730,7 +730,7 @@ bool ThumbTranslatorVisitor::thumb16_WFI() {
}
// YIELD<c>
bool ThumbTranslatorVisitor::thumb16_YIELD() {
bool TranslatorVisitor::thumb16_YIELD() {
if (!options.hook_hint_instructions) {
return true;
}
@ -738,12 +738,12 @@ bool ThumbTranslatorVisitor::thumb16_YIELD() {
}
// NOP<c>
bool ThumbTranslatorVisitor::thumb16_NOP() {
bool TranslatorVisitor::thumb16_NOP() {
return true;
}
// 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");
if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && Common::BitCount(imm8.Bits<0, 3>()) != 1)) {
return UnpredictableInstruction();
@ -759,7 +759,7 @@ bool ThumbTranslatorVisitor::thumb16_IT(Imm<8> imm8) {
// SXTH <Rd>, <Rm>
// 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));
ir.SetRegister(d, ir.SignExtendHalfToWord(half));
return true;
@ -767,7 +767,7 @@ bool ThumbTranslatorVisitor::thumb16_SXTH(Reg m, Reg d) {
// SXTB <Rd>, <Rm>
// 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));
ir.SetRegister(d, ir.SignExtendByteToWord(byte));
return true;
@ -775,7 +775,7 @@ bool ThumbTranslatorVisitor::thumb16_SXTB(Reg m, Reg d) {
// UXTH <Rd>, <Rm>
// 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));
ir.SetRegister(d, ir.ZeroExtendHalfToWord(half));
return true;
@ -783,7 +783,7 @@ bool ThumbTranslatorVisitor::thumb16_UXTH(Reg m, Reg d) {
// UXTB <Rd>, <Rm>
// 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));
ir.SetRegister(d, ir.ZeroExtendByteToWord(byte));
return true;
@ -791,7 +791,7 @@ bool ThumbTranslatorVisitor::thumb16_UXTB(Reg m, Reg d) {
// PUSH <reg_list>
// 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) {
reg_list |= 1 << 14;
}
@ -817,7 +817,7 @@ bool ThumbTranslatorVisitor::thumb16_PUSH(bool M, RegList 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) {
reg_list |= 1 << 15;
}
@ -851,7 +851,7 @@ bool ThumbTranslatorVisitor::thumb16_POP(bool P, RegList reg_list) {
}
// SETEND <endianness>
bool ThumbTranslatorVisitor::thumb16_SETEND(bool E) {
bool TranslatorVisitor::thumb16_SETEND(bool E) {
if (ir.current_location.IT().IsInITBlock()) {
return UnpredictableInstruction();
}
@ -866,13 +866,13 @@ bool ThumbTranslatorVisitor::thumb16_SETEND(bool E) {
// CPS{IE,ID} <a,i,f>
// 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;
}
// REV <Rd>, <Rm>
// 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)));
return true;
}
@ -880,7 +880,7 @@ bool ThumbTranslatorVisitor::thumb16_REV(Reg m, Reg d) {
// REV16 <Rd>, <Rm>
// Rd cannot encode R15.
// 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 upper_half = ir.LeastSignificantHalf(ir.LogicalShiftRight(Rm, ir.Imm8(16), ir.Imm1(0)).result);
const auto lower_half = ir.LeastSignificantHalf(Rm);
@ -895,14 +895,14 @@ bool ThumbTranslatorVisitor::thumb16_REV16(Reg m, Reg d) {
// REVSH <Rd>, <Rm>
// 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)));
ir.SetRegister(d, ir.SignExtendHalfToWord(rev_half));
return true;
}
// BKPT #<imm8>
bool ThumbTranslatorVisitor::thumb16_BKPT([[maybe_unused]] Imm<8> imm8) {
bool TranslatorVisitor::thumb16_BKPT(Imm<8> /*imm8*/) {
ir.ExceptionRaised(Exception::Breakpoint);
ir.UpdateUpperLocationDescriptor();
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>
bool ThumbTranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
bool TranslatorVisitor::thumb16_STMIA(Reg n, RegList reg_list) {
if (Common::BitCount(reg_list) == 0) {
return UnpredictableInstruction();
}
@ -933,7 +933,7 @@ bool ThumbTranslatorVisitor::thumb16_STMIA(Reg n, RegList 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) {
return UnpredictableInstruction();
}
@ -956,7 +956,7 @@ bool ThumbTranslatorVisitor::thumb16_LDMIA(Reg n, RegList reg_list) {
}
// 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()) {
return UnpredictableInstruction();
}
@ -981,12 +981,12 @@ bool ThumbTranslatorVisitor::thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm
return false;
}
bool ThumbTranslatorVisitor::thumb16_UDF() {
bool TranslatorVisitor::thumb16_UDF() {
return UndefinedInstruction();
}
// 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()) {
return UnpredictableInstruction();
}
@ -1001,7 +1001,7 @@ bool ThumbTranslatorVisitor::thumb16_BX(Reg m) {
}
// 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()) {
return UnpredictableInstruction();
}
@ -1015,7 +1015,7 @@ bool ThumbTranslatorVisitor::thumb16_BLX_reg(Reg m) {
}
// SVC #<imm8>
bool ThumbTranslatorVisitor::thumb16_SVC(Imm<8> imm8) {
bool TranslatorVisitor::thumb16_SVC(Imm<8> imm8) {
const u32 imm32 = imm8.ZeroExtend();
ir.UpdateUpperLocationDescriptor();
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2));
@ -1026,7 +1026,7 @@ bool ThumbTranslatorVisitor::thumb16_SVC(Imm<8> imm8) {
}
// 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()) {
return UnpredictableInstruction();
}
@ -1044,7 +1044,7 @@ bool ThumbTranslatorVisitor::thumb16_B_t1(Cond cond, Imm<8> imm8) {
}
// 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()) {
return UnpredictableInstruction();
}

View file

@ -3,12 +3,12 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
// 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> i2{j2 == S};
@ -28,7 +28,7 @@ bool ThumbTranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm
}
// 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> i2{j2 == S};
@ -52,7 +52,7 @@ bool ThumbTranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Im
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> 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;
}
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()) {
return UnpredictableInstruction();
}

View file

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

View file

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

View file

@ -3,9 +3,10 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/assert.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 {
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);
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");
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;
}
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) {
return v.UnpredictableInstruction();
}
@ -52,7 +53,7 @@ static bool Saturation16(ThumbTranslatorVisitor& v, Reg n, Reg d, size_t saturat
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) {
return UnpredictableInstruction();
}
@ -64,7 +65,7 @@ bool ThumbTranslatorVisitor::thumb32_ADR_t2(Imm<1> imm1, Imm<3> imm3, Reg d, Imm
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) {
return UnpredictableInstruction();
}
@ -76,7 +77,7 @@ bool ThumbTranslatorVisitor::thumb32_ADR_t3(Imm<1> imm1, Imm<3> imm3, Reg d, Imm
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) {
return UnpredictableInstruction();
}
@ -89,7 +90,7 @@ bool ThumbTranslatorVisitor::thumb32_ADD_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d,
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) {
return UnpredictableInstruction();
}
@ -109,7 +110,7 @@ bool ThumbTranslatorVisitor::thumb32_BFC(Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5>
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) {
return UnpredictableInstruction();
}
@ -131,7 +132,7 @@ bool ThumbTranslatorVisitor::thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2,
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) {
return UnpredictableInstruction();
}
@ -144,7 +145,7 @@ bool ThumbTranslatorVisitor::thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3,
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) {
return UnpredictableInstruction();
}
@ -155,7 +156,7 @@ bool ThumbTranslatorVisitor::thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> i
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) {
return UnpredictableInstruction();
}
@ -179,15 +180,15 @@ bool ThumbTranslatorVisitor::thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2
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);
}
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);
}
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) {
return UnpredictableInstruction();
}
@ -200,7 +201,7 @@ bool ThumbTranslatorVisitor::thumb32_SUB_imm_2(Imm<1> imm1, Imm<3> imm3, Reg d,
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) {
return UnpredictableInstruction();
}
@ -220,11 +221,11 @@ bool ThumbTranslatorVisitor::thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2
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);
}
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);
}

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
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&);
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) {
return v.UnpredictableInstruction();
}
@ -28,23 +28,23 @@ bool ShiftInstruction(ThumbTranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunct
}
} // 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);
}
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);
}
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);
}
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);
}
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) {
return UnpredictableInstruction();
}
@ -56,7 +56,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg
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) {
return UnpredictableInstruction();
}
@ -70,7 +70,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTB16(Reg d, SignExtendRotation rotate, Re
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) {
return UnpredictableInstruction();
}
@ -83,7 +83,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rota
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) {
return UnpredictableInstruction();
}
@ -98,7 +98,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTAB16(Reg n, Reg d, SignExtendRotation ro
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) {
return UnpredictableInstruction();
}
@ -110,7 +110,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTH(Reg d, SignExtendRotation rotate, Reg
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) {
return UnpredictableInstruction();
}
@ -123,7 +123,7 @@ bool ThumbTranslatorVisitor::thumb32_SXTAH(Reg n, Reg d, SignExtendRotation rota
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) {
return UnpredictableInstruction();
}
@ -135,7 +135,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTB(Reg d, SignExtendRotation rotate, Reg
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) {
return UnpredictableInstruction();
}
@ -147,7 +147,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTB16(Reg d, SignExtendRotation rotate, Re
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) {
return UnpredictableInstruction();
}
@ -160,7 +160,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTAB(Reg n, Reg d, SignExtendRotation rota
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) {
return UnpredictableInstruction();
}
@ -174,7 +174,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTAB16(Reg n, Reg d, SignExtendRotation ro
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) {
return UnpredictableInstruction();
}
@ -186,7 +186,7 @@ bool ThumbTranslatorVisitor::thumb32_UXTH(Reg d, SignExtendRotation rotate, Reg
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) {
return UnpredictableInstruction();
}

View file

@ -3,11 +3,11 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
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) {
return UnpredictableInstruction();
}
@ -21,7 +21,7 @@ bool ThumbTranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
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");
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;
}
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) {
return UnpredictableInstruction();
}
@ -55,7 +55,7 @@ bool ThumbTranslatorVisitor::thumb32_BIC_reg(bool S, Reg n, Imm<3> imm3, Reg d,
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) {
return UnpredictableInstruction();
}
@ -71,7 +71,7 @@ bool ThumbTranslatorVisitor::thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2>
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");
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;
}
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) {
return UnpredictableInstruction();
}
@ -105,7 +105,7 @@ bool ThumbTranslatorVisitor::thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2>
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");
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;
}
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) {
return UnpredictableInstruction();
}
@ -137,7 +137,7 @@ bool ThumbTranslatorVisitor::thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
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");
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;
}
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>();
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;
}
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) {
return UnpredictableInstruction();
}
@ -185,7 +185,7 @@ bool ThumbTranslatorVisitor::thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
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");
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;
}
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) {
return UnpredictableInstruction();
}
@ -221,7 +221,7 @@ bool ThumbTranslatorVisitor::thumb32_ADC_reg(bool S, Reg n, Imm<3> imm3, Reg d,
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) {
return UnpredictableInstruction();
}
@ -238,7 +238,7 @@ bool ThumbTranslatorVisitor::thumb32_SBC_reg(bool S, Reg n, Imm<3> imm3, Reg d,
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) {
return UnpredictableInstruction();
}
@ -253,7 +253,7 @@ bool ThumbTranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, Sh
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");
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;
}
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) {
return UnpredictableInstruction();
}

View file

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

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
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) {
const auto imm32 = imm12.ZeroExtend();
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;
}
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) {
if (m == Reg::PC) {
return v.UnpredictableInstruction();
@ -36,7 +36,7 @@ static bool LoadHalfRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm
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) {
const u32 imm32 = imm12.ZeroExtend();
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;
}
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);
}
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);
}
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) {
return UndefinedInstruction();
}
@ -77,12 +77,12 @@ bool ThumbTranslatorVisitor::thumb32_LDRH_imm8(Reg n, Reg t, bool P, bool U, boo
&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,
&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
// is executed in hypervisor mode if we ever support
// 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);
}
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);
}
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);
}
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) {
return UndefinedInstruction();
}
@ -119,12 +119,12 @@ bool ThumbTranslatorVisitor::thumb32_LDRSH_imm8(Reg n, Reg t, bool P, bool U, bo
&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,
&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
// is executed in hypervisor mode if we ever support
// privileged execution levels.

View file

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

View file

@ -3,8 +3,9 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate.h"
#include "common/bit_util.h"
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 {
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;
}
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 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);
}
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 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);
}
bool ThumbTranslatorVisitor::thumb32_POP(Imm<16> reg_list) {
bool TranslatorVisitor::thumb32_POP(Imm<16> 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);
}
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 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);
}
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 num_regs = static_cast<u32>(Common::BitCount(regs_imm));

View file

@ -3,14 +3,14 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
static bool ITBlockCheck(const A32::IREmitter& ir) {
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)) {
return UnpredictableInstruction();
}
@ -31,7 +31,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12) {
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) {
return UndefinedInstruction();
}
@ -71,7 +71,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_imm8(Reg n, Reg t, bool P, bool U, bool
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)) {
return UnpredictableInstruction();
}
@ -92,7 +92,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_imm12(Reg n, Reg t, Imm<12> imm12) {
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) {
return UnpredictableInstruction();
}
@ -117,7 +117,7 @@ bool ThumbTranslatorVisitor::thumb32_LDR_reg(Reg n, Reg t, Imm<2> imm2, Reg m) {
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
// is executed in hypervisor mode if we ever support
// privileged execution levels.

View file

@ -3,13 +3,13 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
namespace {
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) {
return v.UnpredictableInstruction();
}
@ -23,11 +23,11 @@ bool DivideOperation(ThumbTranslatorVisitor& v, Reg d, Reg m, Reg n, DivideFunct
}
} // 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);
}
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) {
return UnpredictableInstruction();
}
@ -49,7 +49,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLAL(Reg n, Reg dLo, Reg dHi, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -79,7 +79,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLALD(Reg n, Reg dLo, Reg dHi, bool M, Reg
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) {
return UnpredictableInstruction();
}
@ -103,7 +103,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLALXY(Reg n, Reg dLo, Reg dHi, bool N, bo
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) {
return UnpredictableInstruction();
}
@ -133,7 +133,7 @@ bool ThumbTranslatorVisitor::thumb32_SMLSLD(Reg n, Reg dLo, Reg dHi, bool M, Reg
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) {
return UnpredictableInstruction();
}
@ -153,11 +153,11 @@ bool ThumbTranslatorVisitor::thumb32_SMULL(Reg n, Reg dLo, Reg dHi, Reg m) {
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);
}
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) {
return UnpredictableInstruction();
}
@ -179,7 +179,7 @@ bool ThumbTranslatorVisitor::thumb32_UMLAL(Reg n, Reg dLo, Reg dHi, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -199,7 +199,7 @@ bool ThumbTranslatorVisitor::thumb32_UMULL(Reg n, Reg dLo, Reg dHi, Reg m) {
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) {
return UnpredictableInstruction();
}

View file

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

View file

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

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
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);
}
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) {
return UnpredictableInstruction();
}
@ -28,7 +28,7 @@ bool ThumbTranslatorVisitor::thumb32_SADD8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -42,7 +42,7 @@ bool ThumbTranslatorVisitor::thumb32_SADD16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -56,7 +56,7 @@ bool ThumbTranslatorVisitor::thumb32_SASX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -70,7 +70,7 @@ bool ThumbTranslatorVisitor::thumb32_SSAX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -84,7 +84,7 @@ bool ThumbTranslatorVisitor::thumb32_SSUB8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -98,7 +98,7 @@ bool ThumbTranslatorVisitor::thumb32_SSUB16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -112,7 +112,7 @@ bool ThumbTranslatorVisitor::thumb32_UADD8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -126,7 +126,7 @@ bool ThumbTranslatorVisitor::thumb32_UADD16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -140,7 +140,7 @@ bool ThumbTranslatorVisitor::thumb32_UASX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -154,7 +154,7 @@ bool ThumbTranslatorVisitor::thumb32_USAX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -168,7 +168,7 @@ bool ThumbTranslatorVisitor::thumb32_USUB8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -182,7 +182,7 @@ bool ThumbTranslatorVisitor::thumb32_USUB16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -195,7 +195,7 @@ bool ThumbTranslatorVisitor::thumb32_QADD8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -208,7 +208,7 @@ bool ThumbTranslatorVisitor::thumb32_QADD16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -227,7 +227,7 @@ bool ThumbTranslatorVisitor::thumb32_QASX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -246,7 +246,7 @@ bool ThumbTranslatorVisitor::thumb32_QSAX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -259,7 +259,7 @@ bool ThumbTranslatorVisitor::thumb32_QSUB8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -272,7 +272,7 @@ bool ThumbTranslatorVisitor::thumb32_QSUB16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -285,7 +285,7 @@ bool ThumbTranslatorVisitor::thumb32_UQADD8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -298,7 +298,7 @@ bool ThumbTranslatorVisitor::thumb32_UQADD16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -317,7 +317,7 @@ bool ThumbTranslatorVisitor::thumb32_UQASX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -336,7 +336,7 @@ bool ThumbTranslatorVisitor::thumb32_UQSAX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -349,7 +349,7 @@ bool ThumbTranslatorVisitor::thumb32_UQSUB8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -362,7 +362,7 @@ bool ThumbTranslatorVisitor::thumb32_UQSUB16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -375,7 +375,7 @@ bool ThumbTranslatorVisitor::thumb32_SHADD8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -388,7 +388,7 @@ bool ThumbTranslatorVisitor::thumb32_SHADD16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -401,7 +401,7 @@ bool ThumbTranslatorVisitor::thumb32_SHASX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -414,7 +414,7 @@ bool ThumbTranslatorVisitor::thumb32_SHSAX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -427,7 +427,7 @@ bool ThumbTranslatorVisitor::thumb32_SHSUB8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -440,7 +440,7 @@ bool ThumbTranslatorVisitor::thumb32_SHSUB16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -453,7 +453,7 @@ bool ThumbTranslatorVisitor::thumb32_UHADD8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -466,7 +466,7 @@ bool ThumbTranslatorVisitor::thumb32_UHADD16(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -479,7 +479,7 @@ bool ThumbTranslatorVisitor::thumb32_UHASX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -492,7 +492,7 @@ bool ThumbTranslatorVisitor::thumb32_UHSAX(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}
@ -505,7 +505,7 @@ bool ThumbTranslatorVisitor::thumb32_UHSUB8(Reg n, Reg d, Reg m) {
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) {
return UnpredictableInstruction();
}

View file

@ -3,12 +3,12 @@
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
#include "frontend/A32/translate/impl/translate.h"
namespace Dynarmic::A32 {
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) {
return v.UndefinedInstruction();
}
@ -29,21 +29,21 @@ static bool StoreRegister(ThumbTranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2,
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));
}
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));
}
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);
}
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) {
const auto imm32 = imm12.ZeroExtend();
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;
}
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) {
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);
}
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) {
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);
}
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) {
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);
}
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
// is executed in hypervisor mode if we ever support
// 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);
}
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) {
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) {
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);
}
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) {
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);
}
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) {
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);
}
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
// is executed in hypervisor mode if we ever support
// 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);
}
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) {
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) {
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);
}
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) {
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);
}
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) {
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);
}
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
// is executed in hypervisor mode if we ever support
// 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);
}
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) {
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;
struct ArmTranslatorVisitor final {
struct TranslatorVisitor final {
using instruction_return_type = bool;
explicit ArmTranslatorVisitor(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 Arm mode");
}
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options)
: ir(block, descriptor, options.arch_version), options(options)
{}
A32::IREmitter ir;
ConditionalState cond_state = ConditionalState::None;
TranslationOptions options;
bool ConditionPassed(Cond cond);
size_t current_instruction_size;
bool ArmConditionPassed(Cond cond);
bool ThumbConditionPassed();
bool VFPConditionPassed(Cond cond);
bool InterpretThisInstruction();
bool UnpredictableInstruction();
bool UndefinedInstruction();
bool DecodeError();
bool RaiseException(Exception exception);
static u32 ArmExpandImm(int rotate, Imm<8> imm8) {
return Common::RotateRight<u32>(imm8.ZeroExtend(), rotate * 2);
}
struct ImmAndCarry {
u32 imm32;
IR::U1 carry;
@ -49,15 +50,47 @@ struct ArmTranslatorVisitor final {
u32 imm32 = imm8.ZeroExtend();
auto carry_out = carry_in;
if (rotate) {
imm32 = ArmExpandImm(rotate, imm8);
imm32 = Common::RotateRight<u32>(imm8.ZeroExtend(), rotate * 2);
carry_out = ir.Imm1(Common::Bit<31>(imm32));
}
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
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> 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);
@ -369,6 +402,342 @@ struct ArmTranslatorVisitor final {
bool arm_SETEND(bool E);
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
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);

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
*/
#include "frontend/A32/translate/impl/translate_arm.h"
#include "frontend/A32/translate/impl/translate.h"
#include <array>
namespace Dynarmic::A32 {
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()) {
return UnpredictableInstruction();
}
@ -77,7 +77,7 @@ bool ArmTranslatorVisitor::EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, E
}
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){
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VFNMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VFNMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VFMA(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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 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.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 n = ToExtReg(sz, Vn, N);
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.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 n = ToExtReg(sz, Vn, N);
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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]>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction();
@ -477,7 +477,7 @@ bool ArmTranslatorVisitor::vfp_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M,
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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);
if (t == Reg::PC || t2 == Reg::PC || m == ExtReg::S31) {
return UnpredictableInstruction();
@ -513,7 +513,7 @@ bool ArmTranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, s
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::vfp_VMOV_from_i32(Cond cond, Imm<1> i, size_t Vd, Reg t, bool D) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_from_i32(Cond cond, Imm<1> i, size_t Vd, Reg t, bool D) {
if (!VFPConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::vfp_VMOV_from_i16(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<1> i2) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_from_i16(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<1> i2) {
if (!VFPConditionPassed(cond)) {
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>
bool ArmTranslatorVisitor::vfp_VMOV_from_i8(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<2> i2) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_from_i8(Cond cond, Imm<1> i1, size_t Vd, Reg t, bool D, Imm<2> i2) {
if (!VFPConditionPassed(cond)) {
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]>
bool ArmTranslatorVisitor::vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N) {
if (!VFPConditionPassed(cond)) {
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]>
bool ArmTranslatorVisitor::vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2) {
if (!VFPConditionPassed(cond)) {
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]>
bool ArmTranslatorVisitor::vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2) {
if (!VFPConditionPassed(cond)) {
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} <Dd>, <Rt>
bool ArmTranslatorVisitor::vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E) {
if (!VFPConditionPassed(cond)) {
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>.F32 <Sd>, #<imm>
bool ArmTranslatorVisitor::vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L) {
if (!VFPConditionPassed(cond)) {
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>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.F32 <Sd>, <Sm>
bool ArmTranslatorVisitor::vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.f16.f32 <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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.f16.f32 <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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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}.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool E, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool E, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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}.F64 <Dd>, #0.0
bool ArmTranslatorVisitor::vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, bool E) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, bool E) {
if (!VFPConditionPassed(cond)) {
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.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VRINTR(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VRINTZ(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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.F64 <Dd>, <Dm>
bool ArmTranslatorVisitor::vfp_VRINTX(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VRINTX(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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>.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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.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) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm) {
if (!VFPConditionPassed(cond)) {
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.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) {
if (!ConditionPassed(cond)) {
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 (!VFPConditionPassed(cond)) {
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.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) {
if (!ConditionPassed(cond)) {
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 (!VFPConditionPassed(cond)) {
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.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) {
if (!ConditionPassed(cond)) {
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 (!VFPConditionPassed(cond)) {
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}.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) {
if (!ConditionPassed(cond)) {
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 (!VFPConditionPassed(cond)) {
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}.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{
FP::RoundingMode::ToNearest_TieAwayFromZero,
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}.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{
FP::RoundingMode::ToNearest_TieAwayFromZero,
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>
bool ArmTranslatorVisitor::vfp_VMSR(Cond cond, Reg t) {
bool TranslatorVisitor::vfp_VMSR(Cond cond, Reg t) {
if (t == Reg::PC) {
return UnpredictableInstruction();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
return true;
}
@ -1146,8 +1146,8 @@ bool ArmTranslatorVisitor::vfp_VMSR(Cond cond, Reg t) {
}
// VMRS <Rt>, FPSCR
bool ArmTranslatorVisitor::vfp_VMRS(Cond cond, Reg t) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VMRS(Cond cond, Reg t) {
if (!VFPConditionPassed(cond)) {
return true;
}
@ -1163,7 +1163,7 @@ bool ArmTranslatorVisitor::vfp_VMRS(Cond cond, Reg t) {
}
// 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 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();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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 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();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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> <Sd>, [<Rn>{, #+/-<imm>}]
bool ArmTranslatorVisitor::vfp_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) {
if (!VFPConditionPassed(cond)) {
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> <Sd>, [<Rn>{, #+/-<imm>}]
bool ArmTranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) {
if (!ConditionPassed(cond)) {
bool TranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bool sz, Imm<8> imm8) {
if (!VFPConditionPassed(cond)) {
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>
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) {
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();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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) {
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();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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) {
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();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
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>
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) {
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();
}
if (!ConditionPassed(cond)) {
if (!VFPConditionPassed(cond)) {
return true;
}

View file

@ -11,7 +11,7 @@
#include "frontend/A32/decoder/vfp.h"
#include "frontend/A32/location_descriptor.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/types.h"
#include "ir/basic_block.h"
@ -22,18 +22,19 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
const bool single_step = descriptor.SingleStepping();
IR::Block block{descriptor};
ArmTranslatorVisitor visitor{block, descriptor, options};
TranslatorVisitor visitor{block, descriptor, options};
bool should_continue = true;
do {
const u32 arm_pc = visitor.ir.current_location.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);
} 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);
} 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);
} else {
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) {
ArmTranslatorVisitor visitor{block, descriptor, {}};
TranslatorVisitor visitor{block, descriptor, {}};
// TODO: Proper cond handling
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);
} 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);
} 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);
} else {
should_continue = visitor.arm_UDF();
@ -90,88 +91,4 @@ bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descript
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

View file

@ -14,7 +14,7 @@
#include "frontend/A32/ir_emitter.h"
#include "frontend/A32/location_descriptor.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/imm.h"
@ -69,23 +69,24 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
const bool single_step = descriptor.SingleStepping();
IR::Block block{descriptor};
ThumbTranslatorVisitor visitor{block, descriptor, options};
TranslatorVisitor visitor{block, descriptor, options};
bool should_continue = true;
do {
const u32 arm_pc = visitor.ir.current_location.PC();
const auto [thumb_instruction, inst_size] = ReadThumbInstruction(arm_pc, memory_read_code);
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 (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));
} else {
should_continue = visitor.thumb16_UDF();
}
} 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);
} else {
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) {
ThumbTranslatorVisitor visitor{block, descriptor, {}};
TranslatorVisitor visitor{block, descriptor, {}};
const bool is_thumb_16 = IsThumb16(static_cast<u16>(thumb_instruction));
bool should_continue = true;
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));
} else {
should_continue = visitor.thumb16_UDF();
}
} else {
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);
} else {
should_continue = visitor.thumb32_UDF();
@ -147,54 +148,4 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri
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

View file

@ -12,26 +12,26 @@
#include <dynarmic/A32/config.h>
#include "common/assert.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"
using namespace Dynarmic;
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));
const A32::LocationDescriptor location{0, {}, {}};
IR::Block block{location};
A32::ArmTranslatorVisitor visitor{block, location, {}};
A32::TranslatorVisitor visitor{block, location, {}};
matcher.call(visitor, instruction);
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);
for (const auto& ir_inst : block) {

View file

@ -21,7 +21,7 @@
#include "frontend/A32/decoder/asimd.h"
#include "frontend/A32/decoder/vfp.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/A64/decoder/a64.h"
#include "frontend/A64/location_descriptor.h"
@ -36,11 +36,11 @@
using namespace Dynarmic;
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();
} 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();
} else if (auto decoder = A32::DecodeArm<A32::ArmTranslatorVisitor>(instruction)) {
} else if (auto decoder = A32::DecodeArm<A32::TranslatorVisitor>(instruction)) {
return decoder->get().GetName();
}
return "<null>";