diff options
Diffstat (limited to 'externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/packing.cpp')
-rw-r--r-- | externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/packing.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/packing.cpp b/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/packing.cpp new file mode 100644 index 0000000000..5cb88fe47d --- /dev/null +++ b/externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/packing.cpp @@ -0,0 +1,46 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * SPDX-License-Identifier: 0BSD + */ + +#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h" + +namespace Dynarmic::A32 { + +// PKHBT<c> <Rd>, <Rn>, <Rm>{, LSL #<imm>} +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 (!ArmConditionPassed(cond)) { + return true; + } + + const auto shifted = EmitImmShift(ir.GetRegister(m), ShiftType::LSL, imm5, ir.Imm1(false)).result; + const auto lower_half = ir.And(ir.GetRegister(n), ir.Imm32(0x0000FFFF)); + const auto upper_half = ir.And(shifted, ir.Imm32(0xFFFF0000)); + + ir.SetRegister(d, ir.Or(lower_half, upper_half)); + return true; +} + +// PKHTB<c> <Rd>, <Rn>, <Rm>{, ASR #<imm>} +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 (!ArmConditionPassed(cond)) { + return true; + } + + const auto shifted = EmitImmShift(ir.GetRegister(m), ShiftType::ASR, imm5, ir.Imm1(false)).result; + const auto lower_half = ir.And(shifted, ir.Imm32(0x0000FFFF)); + const auto upper_half = ir.And(ir.GetRegister(n), ir.Imm32(0xFFFF0000)); + + ir.SetRegister(d, ir.Or(lower_half, upper_half)); + return true; +} + +} // namespace Dynarmic::A32 |