diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 86a20606..90b60489 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -334,7 +334,7 @@ INST(AESIMC, "AESIMC", "01001 //INST(SHA256SU0, "SHA256SU0", "0101111000101000001010nnnnnddddd") // Data Processing - FP and SIMD - Scalar copy -//INST(DUP_elt_1, "DUP (element)", "01011110000iiiii000001nnnnnddddd") +INST(DUP_elt_1, "DUP (element)", "01011110000iiiii000001nnnnnddddd") // Data Processing - FP and SIMD - Scalar three //INST(FMULX_vec_1, "FMULX", "01011110010mmmmm000111nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_copy.cpp b/src/frontend/A64/translate/impl/simd_copy.cpp index 17d98d9b..6b19ce73 100644 --- a/src/frontend/A64/translate/impl/simd_copy.cpp +++ b/src/frontend/A64/translate/impl/simd_copy.cpp @@ -9,6 +9,21 @@ namespace Dynarmic::A64 { +bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) { + const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); + if (size > 3) return UnallocatedEncoding(); + + const size_t index = imm5.ZeroExtend() >> (size + 1); + const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; + const size_t esize = 8 << size; + + const IR::U128 operand = V(idxdsize, Vn); + const IR::UAny element = ir.VectorGetElement(esize, operand, index); + const IR::U128 result = ir.ZeroExtendToQuad(element); + V(128, Vd, result); + return true; +} + bool TranslatorVisitor::DUP_elt_2(bool Q, Imm<5> imm5, Vec Vn, Vec Vd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); if (size > 3) return UnallocatedEncoding();