From a9ffcf08b1210a0a18422288908c0cff639b5b90 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 15 Sep 2018 13:38:37 +0100 Subject: [PATCH] A64: Implement SQDMULL (vector), vector variant --- src/frontend/A64/decoder/a64.inc | 6 +++--- src/frontend/A64/translate/impl/impl.h | 6 +++--- .../A64/translate/impl/simd_three_different.cpp | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 2b513968..c31734f2 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -437,11 +437,8 @@ INST(FMINP_pair_2, "FMINP (scalar)", "01111 // Data Processing - FP and SIMD - SIMD Scalar three different //INST(SQDMLAL_vec_1, "SQDMLAL, SQDMLAL2 (vector)", "01011110zz1mmmmm100100nnnnnddddd") -//INST(SQDMLAL_vec_2, "SQDMLAL, SQDMLAL2 (vector)", "0Q001110zz1mmmmm100100nnnnnddddd") //INST(SQDMLSL_vec_1, "SQDMLSL, SQDMLSL2 (vector)", "01011110zz1mmmmm101100nnnnnddddd") -//INST(SQDMLSL_vec_2, "SQDMLSL, SQDMLSL2 (vector)", "0Q001110zz1mmmmm101100nnnnnddddd") //INST(SQDMULL_vec_1, "SQDMULL, SQDMULL2 (vector)", "01011110zz1mmmmm110100nnnnnddddd") -//INST(SQDMULL_vec_2, "SQDMULL, SQDMULL2 (vector)", "0Q001110zz1mmmmm110100nnnnnddddd") // Data Processing - FP and SIMD - SIMD Scalar three same INST(SQADD_1, "SQADD", "01011110zz1mmmmm000011nnnnnddddd") @@ -699,6 +696,9 @@ INST(UABDL, "UABDL, UABDL2", "0Q101 INST(UMLAL_vec, "UMLAL, UMLAL2 (vector)", "0Q101110zz1mmmmm100000nnnnnddddd") INST(UMLSL_vec, "UMLSL, UMLSL2 (vector)", "0Q101110zz1mmmmm101000nnnnnddddd") INST(UMULL_vec, "UMULL, UMULL2 (vector)", "0Q101110zz1mmmmm110000nnnnnddddd") +//INST(SQDMLAL_vec_2, "SQDMLAL, SQDMLAL2 (vector)", "0Q001110zz1mmmmm100100nnnnnddddd") +//INST(SQDMLSL_vec_2, "SQDMLSL, SQDMLSL2 (vector)", "0Q001110zz1mmmmm101100nnnnnddddd") +INST(SQDMULL_vec_2, "SQDMULL, SQDMULL2 (vector)", "0Q001110zz1mmmmm110100nnnnnddddd") // Data Processing - FP and SIMD - SIMD three same INST(SHADD, "SHADD", "0Q001110zz1mmmmm000001nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index bcef7905..66ca7ae7 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -546,11 +546,8 @@ struct TranslatorVisitor final { // Data Processing - FP and SIMD - SIMD Scalar three different bool SQDMLAL_vec_1(Imm<2> size, Reg Rm, Reg Rn, Vec Vd); - bool SQDMLAL_vec_2(bool Q, Imm<2> size, Reg Rm, Reg Rn, Vec Vd); bool SQDMLSL_vec_1(Imm<2> size, Reg Rm, Reg Rn, Vec Vd); - bool SQDMLSL_vec_2(bool Q, Imm<2> size, Reg Rm, Reg Rn, Vec Vd); bool SQDMULL_vec_1(Imm<2> size, Reg Rm, Reg Rn, Vec Vd); - bool SQDMULL_vec_2(bool Q, Imm<2> size, Reg Rm, Reg Rn, Vec Vd); // Data Processing - FP and SIMD - SIMD Scalar three same bool SQADD_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd); @@ -770,6 +767,9 @@ struct TranslatorVisitor final { bool UMLAL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); bool UMLSL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); bool UMULL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); + bool SQDMLAL_vec_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); + bool SQDMLSL_vec_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); + bool SQDMULL_vec_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); // Data Processing - FP and SIMD - SIMD three same bool SHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd); diff --git a/src/frontend/A64/translate/impl/simd_three_different.cpp b/src/frontend/A64/translate/impl/simd_three_different.cpp index 01f8dffa..433b813c 100644 --- a/src/frontend/A64/translate/impl/simd_three_different.cpp +++ b/src/frontend/A64/translate/impl/simd_three_different.cpp @@ -249,4 +249,20 @@ bool TranslatorVisitor::USUBL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Subtraction, Signedness::Unsigned); } +bool TranslatorVisitor::SQDMULL_vec_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { + if (size == 0b00 || size == 0b11) { + return ReservedValue(); + } + + const size_t esize = 8 << size.ZeroExtend(); + const size_t part = Q ? 1 : 0; + + const IR::U128 operand1 = Vpart(64, Vn, part); + const IR::U128 operand2 = Vpart(64, Vm, part); + const IR::U128 result = ir.VectorSignedSaturatedDoublingMultiplyLong(esize, operand1, operand2); + + V(128, Vd, result); + return true; +} + } // namespace Dynarmic::A64