diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24bc27cb..75b8b070 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,6 +99,7 @@ add_library(dynarmic frontend/A64/translate/impl/simd_scalar_three_same.cpp frontend/A64/translate/impl/simd_shift_by_immediate.cpp frontend/A64/translate/impl/simd_three_same.cpp + frontend/A64/translate/impl/simd_two_register_misc.cpp frontend/A64/translate/impl/system.cpp frontend/A64/translate/translate.cpp frontend/A64/translate/translate.h diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 3e773138..038339e0 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -635,7 +635,7 @@ INST(INS_elt, "INS (element)", "01101 //INST(CLS_asimd, "CLS (vector)", "0Q001110zz100000010010nnnnnddddd") //INST(CNT, "CNT", "0Q001110zz100000010110nnnnnddddd") //INST(SADALP, "SADALP", "0Q001110zz100000011010nnnnnddddd") -//INST(XTN, "XTN, XTN2", "0Q001110zz100001001010nnnnnddddd") +INST(XTN, "XTN, XTN2", "0Q001110zz100001001010nnnnnddddd") //INST(FCVTN, "FCVTN, FCVTN2", "0Q0011100z100001011010nnnnnddddd") //INST(FCVTL, "FCVTL, FCVTL2", "0Q0011100z100001011110nnnnnddddd") //INST(URECPE, "URECPE", "0Q0011101z100001110010nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/impl.cpp b/src/frontend/A64/translate/impl/impl.cpp index 64d6bd20..e70f3d3d 100644 --- a/src/frontend/A64/translate/impl/impl.cpp +++ b/src/frontend/A64/translate/impl/impl.cpp @@ -229,6 +229,17 @@ IR::U128 TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) { return ir.ZeroExtendToQuad(ir.VectorGetElement(bitsize, V(128, vec), part)); } +void TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part, IR::U128 value) { + ASSERT(part == 0 || part == 1); + if (part == 0) { + ASSERT(bitsize == 64); + V(128, vec, value); + } else { + ASSERT(bitsize == 64); + V(128, vec, ir.VectorSetElement(64, V(128, vec), 1, ir.VectorGetElement(64, value, 0))); + } +} + IR::UAny TranslatorVisitor::Vpart_scalar(size_t bitsize, Vec vec, size_t part) { ASSERT(part == 0 || part == 1); if (part == 0) { diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 43c5d7b0..b46b660d 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -56,6 +56,7 @@ struct TranslatorVisitor final { void V_scalar(size_t bitsize, Vec vec, IR::UAny value); IR::U128 Vpart(size_t bitsize, Vec vec, size_t part); + void Vpart(size_t bitsize, Vec vec, size_t part, IR::U128 value); IR::UAny Vpart_scalar(size_t bitsize, Vec vec, size_t part); void Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::UAny value); @@ -757,7 +758,7 @@ struct TranslatorVisitor final { bool CLS_asimd(bool Q, Imm<2> size, Vec Vn, Vec Vd); bool CNT(bool Q, Imm<2> size, Vec Vn, Vec Vd); bool SADALP(bool Q, Imm<2> size, Vec Vn, Vec Vd); - bool XTN(bool Q, Imm<2> size, Vec Vn, Reg Rd); + bool XTN(bool Q, Imm<2> size, Vec Vn, Vec Vd); bool FCVTN(bool Q, bool sz, Vec Vn, Reg Rd); bool FCVTL(bool Q, bool sz, Reg Rn, Vec Vd); bool URECPE(bool Q, bool sz, Vec Vn, Vec Vd); diff --git a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp new file mode 100644 index 00000000..3d4500e7 --- /dev/null +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -0,0 +1,26 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include "frontend/A64/translate/impl/impl.h" + +namespace Dynarmic::A64 { + +bool TranslatorVisitor::XTN(bool Q, Imm<2> size, Vec Vn, Vec Vd) { + if (size == 0b11) { + return ReservedValue(); + } + const size_t esize = 8 << size.ZeroExtend(); + const size_t datasize = 64; + const size_t part = Q ? 1 : 0; + + const IR::U128 operand = V(2 * datasize, Vn); + const IR::U128 result = ir.VectorNarrow(2 * esize, operand); + + Vpart(datasize, Vd, part, result); + return true; +} + +} // namespace Dynarmic::A64