A64: Implement TBL and TBX

This commit is contained in:
MerryMage 2018-08-18 21:09:12 +01:00
parent 89d08c7d61
commit 0c18b85c27
4 changed files with 44 additions and 4 deletions

View file

@ -164,6 +164,7 @@ add_library(dynarmic
frontend/A64/translate/impl/simd_sha.cpp
frontend/A64/translate/impl/simd_sha512.cpp
frontend/A64/translate/impl/simd_shift_by_immediate.cpp
frontend/A64/translate/impl/simd_table_lookup.cpp
frontend/A64/translate/impl/simd_three_different.cpp
frontend/A64/translate/impl/simd_three_same.cpp
frontend/A64/translate/impl/simd_three_same_extra.cpp

View file

@ -511,8 +511,8 @@ INST(FMUL_elt_2, "FMUL (by element)", "01011
//INST(FMULX_elt_2, "FMULX (by element)", "011111111zLMmmmm1001H0nnnnnddddd")
// Data Processing - FP and SIMD - SIMD Table Lookup
//INST(TBL, "TBL", "0Q001110000mmmmm0LL000nnnnnddddd")
//INST(TBX, "TBX", "0Q001110000mmmmm0LL100nnnnnddddd")
INST(TBL, "TBL", "0Q001110000mmmmm0LL000nnnnnddddd")
INST(TBX, "TBX", "0Q001110000mmmmm0LL100nnnnnddddd")
// Data Processing - FP and SIMD - SIMD Permute
INST(UZP1, "UZP1", "0Q001110zz0mmmmm000110nnnnnddddd")

View file

@ -621,8 +621,8 @@ struct TranslatorVisitor final {
bool FMULX_elt_2(bool sz, bool L, bool M, Vec Vm, bool H, Vec Vn, Vec Vd);
// Data Processing - FP and SIMD - SIMD Table Lookup
bool TBL(bool Q, Vec Vm, Imm<2> len, Vec Vn, Vec Vd);
bool TBX(bool Q, Vec Vm, Imm<2> len, Vec Vn, Vec Vd);
bool TBL(bool Q, Vec Vm, Imm<2> len, size_t Vn, Vec Vd);
bool TBX(bool Q, Vec Vm, Imm<2> len, size_t Vn, Vec Vd);
// Data Processing - FP and SIMD - SIMD Permute
bool UZP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd);

View file

@ -0,0 +1,39 @@
/* 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 {
static bool TableLookup(TranslatorVisitor& v, bool Q, Vec Vm, Imm<2> len, bool is_tbl, size_t Vn, Vec Vd) {
const size_t datasize = Q ? 128 : 64;
const IR::Table table = v.ir.VectorTable([&]{
std::vector<IR::U128> result;
for (size_t i = 0; i < len.ZeroExtend<size_t>() + 1; ++i) {
result.emplace_back(v.ir.GetQ(static_cast<Vec>((Vn + i) % 32)));
}
return result;
}());
const IR::U128 indicies = v.ir.GetQ(Vm);
const IR::U128 defaults = is_tbl ? v.ir.ZeroVector() : v.ir.GetQ(Vd);
const IR::U128 result = v.ir.VectorTableLookup(defaults, table, indicies);
v.V(datasize, Vd, datasize == 128 ? result : v.ir.VectorZeroUpper(result));
return true;
}
bool TranslatorVisitor::TBL(bool Q, Vec Vm, Imm<2> len, size_t Vn, Vec Vd) {
return TableLookup(*this, Q, Vm, len, true, Vn, Vd);
}
bool TranslatorVisitor::TBX(bool Q, Vec Vm, Imm<2> len, size_t Vn, Vec Vd) {
return TableLookup(*this, Q, Vm, len, false, Vn, Vd);
}
} // namespace Dynarmic::A64