A32: Implement ASIMD VSWP
A trivial one to implement, this just swaps the contents of two registers in place.
This commit is contained in:
parent
d0d50c4824
commit
659d78c9c4
4 changed files with 48 additions and 1 deletions
|
@ -124,6 +124,7 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
|
|||
frontend/A32/PSR.h
|
||||
frontend/A32/translate/impl/asimd_load_store_structures.cpp
|
||||
frontend/A32/translate/impl/asimd_three_same.cpp
|
||||
frontend/A32/translate/impl/asimd_two_regs_misc.cpp
|
||||
frontend/A32/translate/impl/barrier.cpp
|
||||
frontend/A32/translate/impl/branch.cpp
|
||||
frontend/A32/translate/impl/coprocessor.cpp
|
||||
|
|
|
@ -94,7 +94,7 @@ INST(asimd_VBIF, "VBIF", "111100110D11nnnndddd000
|
|||
//INST(asimd_VCLT_zero, "VCLT (zero)", "111100111-11--01----0x100x-0----") // ASIMD
|
||||
//INST(asimd_VABS, "VABS", "111100111-11--01----0x110x-0----") // ASIMD
|
||||
//INST(asimd_VNEG, "VNEG", "111100111-11--01----0x111x-0----") // ASIMD
|
||||
//INST(asimd_VSWP, "VSWP", "111100111-11--10----00000x-0----") // ASIMD
|
||||
INST(asimd_VSWP, "VSWP", "111100111D110010dddd00000QM0mmmm") // ASIMD
|
||||
//INST(asimd_VTRN, "VTRN", "111100111-11--10----00001x-0----") // ASIMD
|
||||
//INST(asimd_VUZP, "VUZP", "111100111-11--10----00010x-0----") // ASIMD
|
||||
//INST(asimd_VZIP, "VZIP", "111100111-11--10----00011x-0----") // ASIMD
|
||||
|
|
43
src/frontend/A32/translate/impl/asimd_two_regs_misc.cpp
Normal file
43
src/frontend/A32/translate/impl/asimd_two_regs_misc.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2020 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "common/bit_util.h"
|
||||
|
||||
#include "frontend/A32/translate/impl/translate_arm.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
namespace {
|
||||
ExtReg ToExtRegD(size_t base, bool bit) {
|
||||
return ExtReg::D0 + (base + (bit ? 16 : 0));
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
bool ArmTranslatorVisitor::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();
|
||||
}
|
||||
|
||||
// Swapping the same register results in the same contents.
|
||||
const auto d = ToExtRegD(Vd, D);
|
||||
const auto m = ToExtRegD(Vm, M);
|
||||
if (d == m) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t regs = Q ? 2 : 1;
|
||||
for (size_t i = 0; i < regs; i++) {
|
||||
const auto d_index = d + i;
|
||||
const auto m_index = m + i;
|
||||
|
||||
const auto reg_d = ir.GetExtendedRegister(d_index);
|
||||
const auto reg_m = ir.GetExtendedRegister(m_index);
|
||||
|
||||
ir.SetExtendedRegister(m_index, reg_d);
|
||||
ir.SetExtendedRegister(d_index, reg_m);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace Dynarmic::A32
|
|
@ -439,6 +439,9 @@ struct ArmTranslatorVisitor final {
|
|||
bool asimd_VBIT(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VBIF(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
|
||||
// Advanced SIMD two register, miscellaneous
|
||||
bool asimd_VSWP(bool D, size_t Vd, bool Q, bool M, size_t Vm);
|
||||
|
||||
// Advanced SIMD load/store structures
|
||||
bool v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t sz, size_t align, Reg m);
|
||||
bool v8_VLD_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t sz, size_t align, Reg m);
|
||||
|
|
Loading…
Reference in a new issue