A64: Implement SIMD instructions XTN, XTN2

This commit is contained in:
MerryMage 2018-02-10 16:47:50 +00:00
parent 132c783320
commit e858ce0b35
5 changed files with 41 additions and 2 deletions

View file

@ -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

View file

@ -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")

View file

@ -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) {

View file

@ -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);

View file

@ -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<size_t>();
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