A64: Implement UZP1 and UZP2
This commit is contained in:
parent
26d77c6f09
commit
bebe7235ae
2 changed files with 49 additions and 5 deletions
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue