diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d944b9e..29d99dc3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index fce59809..71604561 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -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") diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 308b9f5b..0342ede6 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -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); diff --git a/src/frontend/A64/translate/impl/simd_table_lookup.cpp b/src/frontend/A64/translate/impl/simd_table_lookup.cpp new file mode 100644 index 00000000..a40d4073 --- /dev/null +++ b/src/frontend/A64/translate/impl/simd_table_lookup.cpp @@ -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 result; + for (size_t i = 0; i < len.ZeroExtend() + 1; ++i) { + result.emplace_back(v.ir.GetQ(static_cast((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