A64: Implement UZP1 and UZP2

This commit is contained in:
Lioncash 2018-04-25 16:07:58 -04:00 committed by MerryMage
parent 26d77c6f09
commit bebe7235ae
2 changed files with 49 additions and 5 deletions

View file

@ -514,10 +514,10 @@ INST(SLI_1, "SLI", "01111
//INST(TBX, "TBX", "0Q001110000mmmmm0LL100nnnnnddddd") //INST(TBX, "TBX", "0Q001110000mmmmm0LL100nnnnnddddd")
// Data Processing - FP and SIMD - SIMD Permute // Data Processing - FP and SIMD - SIMD Permute
//INST(UZP1, "UZP1", "0Q001110zz0mmmmm000110nnnnnddddd") INST(UZP1, "UZP1", "0Q001110zz0mmmmm000110nnnnnddddd")
INST(TRN1, "TRN1", "0Q001110zz0mmmmm001010nnnnnddddd") INST(TRN1, "TRN1", "0Q001110zz0mmmmm001010nnnnnddddd")
INST(ZIP1, "ZIP1", "0Q001110zz0mmmmm001110nnnnnddddd") INST(ZIP1, "ZIP1", "0Q001110zz0mmmmm001110nnnnnddddd")
//INST(UZP2, "UZP2", "0Q001110zz0mmmmm010110nnnnnddddd") INST(UZP2, "UZP2", "0Q001110zz0mmmmm010110nnnnnddddd")
INST(TRN2, "TRN2", "0Q001110zz0mmmmm011010nnnnnddddd") INST(TRN2, "TRN2", "0Q001110zz0mmmmm011010nnnnnddddd")
INST(ZIP2, "ZIP2", "0Q001110zz0mmmmm011110nnnnnddddd") INST(ZIP2, "ZIP2", "0Q001110zz0mmmmm011110nnnnnddddd")

View file

@ -8,13 +8,13 @@
#include "frontend/A64/translate/impl/impl.h" #include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 { namespace Dynarmic::A64 {
namespace {
enum class Transposition { enum class Transposition {
TRN1, TRN1,
TRN2, TRN2,
}; };
static void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
Transposition type) { Transposition type) {
const size_t datasize = Q ? 128 : 64; const size_t datasize = Q ? 128 : 64;
const u8 esize = static_cast<u8>(8 << size.ZeroExtend()); const u8 esize = static_cast<u8>(8 << size.ZeroExtend());
@ -63,6 +63,32 @@ static void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, V
v.V(datasize, Vd, result); v.V(datasize, Vd, result);
} }
enum class UnzipType {
Even,
Odd,
};
void VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, UnzipType type) {
const size_t datasize = Q ? 128 : 64;
const size_t esize = 8 << size.ZeroExtend();
const IR::U128 n = v.V(datasize, Vn);
const IR::U128 m = v.V(datasize, Vm);
IR::U128 result = [&] {
if (type == UnzipType::Even) {
return v.ir.VectorDeinterleaveEven(esize, n, m);
}
return v.ir.VectorDeinterleaveOdd(esize, n, m);
}();
if (datasize == 64) {
result = v.ir.VectorShuffleWords(result, 0b11011000);
}
v.V(datasize, Vd, result);
}
} // Anonymous namespace
bool TranslatorVisitor::TRN1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { bool TranslatorVisitor::TRN1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
if (!Q && size == 0b11) { if (!Q && size == 0b11) {
return ReservedValue(); return ReservedValue();
@ -81,6 +107,24 @@ bool TranslatorVisitor::TRN2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
return true; return true;
} }
bool TranslatorVisitor::UZP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
if (size == 0b11 && !Q) {
return ReservedValue();
}
VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even);
return true;
}
bool TranslatorVisitor::UZP2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
if (size == 0b11 && !Q) {
return ReservedValue();
}
VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd);
return true;
}
bool TranslatorVisitor::ZIP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { bool TranslatorVisitor::ZIP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
if (size == 0b11 && !Q) { if (size == 0b11 && !Q) {
return ReservedValue(); return ReservedValue();