From cb5e5c5d49da90f5142afbeec47cfe4b181e73c6 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 17 Aug 2018 18:12:36 -0400 Subject: [PATCH] A64: Implement SADALP and UADALP While we're at it we can join the code for SADDLP and UADDLP with these instructions, since the only difference is we do an accumulate at the end of the operation. --- src/frontend/A64/decoder/a64.inc | 4 +- .../translate/impl/simd_two_register_misc.cpp | 75 +++++++++++-------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 00b359a6..3d82d9fa 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -572,7 +572,7 @@ INST(SADDLP, "SADDLP", "0Q001 //INST(SUQADD_2, "SUQADD", "0Q001110zz100000001110nnnnnddddd") //INST(CLS_asimd, "CLS (vector)", "0Q001110zz100000010010nnnnnddddd") INST(CNT, "CNT", "0Q001110zz100000010110nnnnnddddd") -//INST(SADALP, "SADALP", "0Q001110zz100000011010nnnnnddddd") +INST(SADALP, "SADALP", "0Q001110zz100000011010nnnnnddddd") //INST(SQABS_2, "SQABS", "0Q001110zz100000011110nnnnnddddd") INST(CMGT_zero_2, "CMGT (zero)", "0Q001110zz100000100010nnnnnddddd") INST(CMEQ_zero_2, "CMEQ (zero)", "0Q001110zz100000100110nnnnnddddd") @@ -617,7 +617,7 @@ INST(REV32_asimd, "REV32 (vector)", "0Q101 INST(UADDLP, "UADDLP", "0Q101110zz100000001010nnnnnddddd") //INST(USQADD_2, "USQADD", "0Q101110zz100000001110nnnnnddddd") //INST(CLZ_asimd, "CLZ (vector)", "0Q101110zz100000010010nnnnnddddd") -//INST(UADALP, "UADALP", "0Q101110zz100000011010nnnnnddddd") +INST(UADALP, "UADALP", "0Q101110zz100000011010nnnnnddddd") //INST(SQNEG_2, "SQNEG", "0Q101110zz100000011110nnnnnddddd") INST(CMGE_zero_2, "CMGE (zero)", "0Q101110zz100000100010nnnnnddddd") INST(CMLE_2, "CMLE (zero)", "0Q101110zz100000100110nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp index 130e5d13..94715e2a 100644 --- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp @@ -156,6 +156,41 @@ bool SaturatedNarrow(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, return true; } +enum class PairedAddLongExtraBehavior { + None, + Accumulate, +}; + +bool PairedAddLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, Signedness sign, + PairedAddLongExtraBehavior behavior) { + if (size == 0b11) { + return v.ReservedValue(); + } + + const size_t esize = 8 << size.ZeroExtend(); + const size_t datasize = Q ? 128 : 64; + + const IR::U128 operand = v.V(datasize, Vn); + IR::U128 result = [&] { + if (sign == Signedness::Signed) { + return v.ir.VectorPairedAddSignedWiden(esize, operand); + } + + return v.ir.VectorPairedAddUnsignedWiden(esize, operand); + }(); + + if (behavior == PairedAddLongExtraBehavior::Accumulate) { + result = v.ir.VectorAdd(esize * 2, v.V(datasize, Vd), result); + } + + if (datasize == 64) { + result = v.ir.VectorZeroUpper(result); + } + + v.V(datasize, Vd, result); + return true; +} + } // Anonymous namespace bool TranslatorVisitor::CNT(bool Q, Imm<2> size, Vec Vn, Vec Vd) { @@ -564,42 +599,20 @@ bool TranslatorVisitor::REV64_asimd(bool Q, Imm<2> size, Vec Vn, Vec Vd) { return true; } -bool TranslatorVisitor::UADDLP(bool Q, Imm<2> size, Vec Vn, Vec Vd) { - if (size == 0b11) { - return ReservedValue(); - } - - const size_t esize = 8 << size.ZeroExtend(); - const size_t datasize = Q ? 128 : 64; - - const IR::U128 operand = V(datasize, Vn); - IR::U128 result = ir.VectorPairedAddUnsignedWiden(esize, operand); - - if (datasize == 64) { - result = ir.VectorZeroUpper(result); - } - - V(datasize, Vd, result); - return true; +bool TranslatorVisitor::SADALP(bool Q, Imm<2> size, Vec Vn, Vec Vd) { + return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Signed, PairedAddLongExtraBehavior::Accumulate); } bool TranslatorVisitor::SADDLP(bool Q, Imm<2> size, Vec Vn, Vec Vd) { - if (size == 0b11) { - return ReservedValue(); - } + return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Signed, PairedAddLongExtraBehavior::None); +} - const size_t esize = 8 << size.ZeroExtend(); - const size_t datasize = Q ? 128 : 64; +bool TranslatorVisitor::UADALP(bool Q, Imm<2> size, Vec Vn, Vec Vd) { + return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Unsigned, PairedAddLongExtraBehavior::Accumulate); +} - const IR::U128 operand = V(datasize, Vn); - IR::U128 result = ir.VectorPairedAddSignedWiden(esize, operand); - - if (datasize == 64) { - result = ir.VectorZeroUpper(result); - } - - V(datasize, Vd, result); - return true; +bool TranslatorVisitor::UADDLP(bool Q, Imm<2> size, Vec Vn, Vec Vd) { + return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Unsigned, PairedAddLongExtraBehavior::None); } bool TranslatorVisitor::SCVTF_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {