From c022a778d6de8333296b63d12d5f5a7df9d3907c Mon Sep 17 00:00:00 2001 From: merry Date: Sun, 20 Mar 2022 00:29:59 +0000 Subject: [PATCH] A32: Implement SHA256H, SHA256H2 --- src/dynarmic/frontend/A32/decoder/asimd.inc | 2 ++ .../A32/translate/impl/a32_translate_impl.h | 2 ++ .../A32/translate/impl/asimd_three_regs.cpp | 36 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/dynarmic/frontend/A32/decoder/asimd.inc b/src/dynarmic/frontend/A32/decoder/asimd.inc index 119ad330..635df8e3 100644 --- a/src/dynarmic/frontend/A32/decoder/asimd.inc +++ b/src/dynarmic/frontend/A32/decoder/asimd.inc @@ -50,6 +50,8 @@ INST(asimd_VPMAX_float, "VPMAX (floating-point)", "111100110D0znnnndddd111 INST(asimd_VPMIN_float, "VPMIN (floating-point)", "111100110D1znnnndddd1111NQM0mmmm") // ASIMD INST(asimd_VRECPS, "VRECPS", "111100100D0znnnndddd1111NQM1mmmm") // ASIMD INST(asimd_VRSQRTS, "VRSQRTS", "111100100D1znnnndddd1111NQM1mmmm") // ASIMD +INST(v8_SHA256H, "SHA256H", "111100110D00nnnndddd1100NQM0mmmm") // v8 +INST(v8_SHA256H2, "SHA256H2", "111100110D01nnnndddd1100NQM0mmmm") // v8 // Three registers of different lengths INST(asimd_VADDL, "VADDL/VADDW", "1111001U1Dzznnnndddd000oN0M0mmmm") // ASIMD diff --git a/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h b/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h index 76243b31..56ad5c1b 100644 --- a/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h +++ b/src/dynarmic/frontend/A32/translate/impl/a32_translate_impl.h @@ -875,6 +875,8 @@ struct TranslatorVisitor final { bool asimd_VPMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VRECPS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VRSQRTS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); + bool v8_SHA256H(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); + bool v8_SHA256H2(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); // Advanced SIMD three registers with different lengths bool asimd_VADDL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm); diff --git a/src/dynarmic/frontend/A32/translate/impl/asimd_three_regs.cpp b/src/dynarmic/frontend/A32/translate/impl/asimd_three_regs.cpp index 44d616dc..a1b5cf4d 100644 --- a/src/dynarmic/frontend/A32/translate/impl/asimd_three_regs.cpp +++ b/src/dynarmic/frontend/A32/translate/impl/asimd_three_regs.cpp @@ -831,6 +831,42 @@ bool TranslatorVisitor::asimd_VRSQRTS(bool D, bool sz, size_t Vn, size_t Vd, boo }); } +bool TranslatorVisitor::v8_SHA256H(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { + if (!Q || Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm)) { + return UndefinedInstruction(); + } + + const auto d = ToVector(Q, Vd, D); + const auto n = ToVector(Q, Vn, N); + const auto m = ToVector(Q, Vm, M); + + const auto x = ir.GetVector(d); + const auto y = ir.GetVector(n); + const auto w = ir.GetVector(m); + const auto result = ir.SHA256Hash(x, y, w, true); + + ir.SetVector(d, result); + return true; +} + +bool TranslatorVisitor::v8_SHA256H2(bool D, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { + if (!Q || Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm)) { + return UndefinedInstruction(); + } + + const auto n = ToVector(Q, Vn, N); + const auto d = ToVector(Q, Vd, D); + const auto m = ToVector(Q, Vm, M); + + const auto x = ir.GetVector(n); + const auto y = ir.GetVector(d); + const auto w = ir.GetVector(m); + const auto result = ir.SHA256Hash(x, y, w, false); + + ir.SetVector(d, result); + return true; +} + // ASIMD Three registers of different length bool TranslatorVisitor::asimd_VADDL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm) {