A32: Implement ASIMD VTBL
This commit is contained in:
parent
28f27bc19d
commit
b0beecdd41
3 changed files with 27 additions and 1 deletions
|
@ -109,7 +109,7 @@ INST(asimd_VRSQRTE, "VRSQRTE", "111100111D11zz11dddd010
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
INST(asimd_VEXT, "VEXT", "111100101D11nnnnddddiiiiNQM0mmmm") // ASIMD
|
INST(asimd_VEXT, "VEXT", "111100101D11nnnnddddiiiiNQM0mmmm") // ASIMD
|
||||||
//INST(asimd_VTBL, "VTBL", "111100111D11nnnndddd10zzN0M0mmmm") // ASIMD
|
INST(asimd_VTBL, "VTBL", "111100111D11nnnndddd10zzN0M0mmmm") // ASIMD
|
||||||
//INST(asimd_VTBX, "VTBX", "111100111D11nnnndddd10zzN1M0mmmm") // ASIMD
|
//INST(asimd_VTBX, "VTBX", "111100111D11nnnndddd10zzN1M0mmmm") // ASIMD
|
||||||
//INST(asimd_VDUP_scalar, "VDUP (scalar)", "111100111D11iiiidddd11000QM0mmmm") // ASIMD
|
//INST(asimd_VDUP_scalar, "VDUP (scalar)", "111100111D11iiiidddd11000QM0mmmm") // ASIMD
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,29 @@ bool ArmTranslatorVisitor::asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::asimd_VTBL(bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm) {
|
||||||
|
const size_t length = len + 1;
|
||||||
|
const auto d = ToVector(false, Vd, D);
|
||||||
|
const auto m = ToVector(false, Vm, M);
|
||||||
|
const auto n = ToVector(false, Vn, N);
|
||||||
|
|
||||||
|
if (RegNumber(n) + length > 32) {
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
const IR::U64 table0 = ir.GetExtendedRegister(n);
|
||||||
|
const IR::U64 table1 = length >= 2 ? IR::U64{ir.GetExtendedRegister(n + 1)} : ir.Imm64(0);
|
||||||
|
const IR::U64 table2 = length >= 3 ? IR::U64{ir.GetExtendedRegister(n + 2)} : ir.Imm64(0);
|
||||||
|
const IR::U64 table3 = length == 4 ? IR::U64{ir.GetExtendedRegister(n + 3)} : ir.Imm64(0);
|
||||||
|
|
||||||
|
const IR::Table table = ir.VectorTable(length <= 2
|
||||||
|
? std::vector<IR::U128>{ir.Pack2x64To1x128(table0, table1)}
|
||||||
|
: std::vector<IR::U128>{ir.Pack2x64To1x128(table0, table1), ir.Pack2x64To1x128(table2, table3)});
|
||||||
|
const IR::U128 indicies = ir.GetVector(m);
|
||||||
|
const IR::U128 result = ir.VectorTableLookup(ir.ZeroVector(), table, indicies);
|
||||||
|
|
||||||
|
ir.SetVector(d, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A32
|
} // namespace Dynarmic::A32
|
||||||
|
|
|
@ -505,6 +505,7 @@ struct ArmTranslatorVisitor final {
|
||||||
|
|
||||||
// Advanced SIMD miscellaneous
|
// Advanced SIMD miscellaneous
|
||||||
bool asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4, bool N, bool Q, bool M, size_t Vm);
|
bool asimd_VEXT(bool D, size_t Vn, size_t Vd, Imm<4> imm4, bool N, bool Q, bool M, size_t Vm);
|
||||||
|
bool asimd_VTBL(bool D, size_t Vn, size_t Vd, size_t len, bool N, bool M, size_t Vm);
|
||||||
|
|
||||||
// Advanced SIMD load/store structures
|
// Advanced SIMD load/store structures
|
||||||
bool v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t sz, size_t align, Reg m);
|
bool v8_VST_multiple(bool D, Reg n, size_t Vd, Imm<4> type, size_t sz, size_t align, Reg m);
|
||||||
|
|
Loading…
Reference in a new issue