From 24479ecbe5a88595252ebd3e2348bba65137711f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 10 Apr 2019 15:05:56 -0400 Subject: [PATCH 1/3] simd_scalar_shift_by_immediate: Migrate SQSHL implementation to file-scope function This will allow it to be reused for the implementation of UQSHL. --- .../impl/simd_scalar_shift_by_immediate.cpp | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp index 57a3d146..1135ad88 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp @@ -30,6 +30,22 @@ enum class FloatConversionDirection { FloatToFixed, }; +bool SaturatingShiftLeft(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { + if (immh == 0b0000) { + return v.UnallocatedEncoding(); + } + + const size_t esize = 8U << Common::HighestSetBit(immh.ZeroExtend()); + const size_t shift_amount = concatenate(immh, immb).ZeroExtend() - esize; + + const IR::U128 operand = v.ir.ZeroExtendToQuad(v.V_scalar(esize, Vn)); + const IR::U128 shift = v.ir.ZeroExtendToQuad(v.I(esize, shift_amount)); + const IR::U128 result = v.ir.VectorSignedSaturatedShiftLeft(esize, operand, shift); + + v.ir.SetQ(Vd, result); + return true; +} + bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, Signedness signedness) { if (!immh.Bit<3>()) { @@ -254,19 +270,7 @@ bool TranslatorVisitor::SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { } bool TranslatorVisitor::SQSHL_imm_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return UnallocatedEncoding(); - } - - const size_t esize = 8U << Common::HighestSetBit(immh.ZeroExtend()); - const size_t shift_amount = concatenate(immh, immb).ZeroExtend() - esize; - - const IR::U128 operand = ir.ZeroExtendToQuad(V_scalar(esize, Vn)); - const IR::U128 shift = ir.ZeroExtendToQuad(I(esize, shift_amount)); - const IR::U128 result = ir.VectorSignedSaturatedShiftLeft(esize, operand, shift); - - ir.SetQ(Vd, result); - return true; + return SaturatingShiftLeft(*this, immh, immb, Vn, Vd); } bool TranslatorVisitor::SQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { From 276957223128725d44c50c657cf72bb3f34f5f0f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 10 Apr 2019 15:10:07 -0400 Subject: [PATCH 2/3] A64: Implement UQSHL (immediate)'s scalar variant Like SQSHL's immediate scalar variant, we can also implement UQSHL's immediate scalar variant in terms of the vector variant for the time being. --- src/frontend/A64/decoder/a64.inc | 2 +- .../impl/simd_scalar_shift_by_immediate.cpp | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 80863f88..4ced0b8a 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -524,7 +524,7 @@ INST(URSRA_1, "URSRA", "01111 INST(SRI_1, "SRI", "011111110IIIIiii010001nnnnnddddd") INST(SLI_1, "SLI", "011111110IIIIiii010101nnnnnddddd") //INST(SQSHLU_1, "SQSHLU", "011111110IIIIiii011001nnnnnddddd") -//INST(UQSHL_imm_1, "UQSHL (immediate)", "011111110IIIIiii011101nnnnnddddd") +INST(UQSHL_imm_1, "UQSHL (immediate)", "011111110IIIIiii011101nnnnnddddd") INST(SQSHRUN_1, "SQSHRUN, SQSHRUN2", "011111110IIIIiii100001nnnnnddddd") //INST(SQRSHRUN_1, "SQRSHRUN, SQRSHRUN2", "011111110IIIIiii100011nnnnnddddd") INST(UQSHRN_1, "UQSHRN, UQSHRN2", "011111110IIIIiii100101nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp index 1135ad88..5ecb8f1b 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp @@ -30,7 +30,7 @@ enum class FloatConversionDirection { FloatToFixed, }; -bool SaturatingShiftLeft(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { +bool SaturatingShiftLeft(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) { if (immh == 0b0000) { return v.UnallocatedEncoding(); } @@ -40,7 +40,12 @@ bool SaturatingShiftLeft(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, const IR::U128 operand = v.ir.ZeroExtendToQuad(v.V_scalar(esize, Vn)); const IR::U128 shift = v.ir.ZeroExtendToQuad(v.I(esize, shift_amount)); - const IR::U128 result = v.ir.VectorSignedSaturatedShiftLeft(esize, operand, shift); + const IR::U128 result = [&v, esize, operand, shift, sign] { + if (sign == Signedness::Signed) { + return v.ir.VectorSignedSaturatedShiftLeft(esize, operand, shift); + } + return v.ir.VectorUnsignedSaturatedShiftLeft(esize, operand, shift); + }(); v.ir.SetQ(Vd, result); return true; @@ -270,7 +275,7 @@ bool TranslatorVisitor::SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { } bool TranslatorVisitor::SQSHL_imm_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - return SaturatingShiftLeft(*this, immh, immb, Vn, Vd); + return SaturatingShiftLeft(*this, immh, immb, Vn, Vd, Signedness::Signed); } bool TranslatorVisitor::SQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { @@ -312,6 +317,10 @@ bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return true; } +bool TranslatorVisitor::UQSHL_imm_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { + return SaturatingShiftLeft(*this, immh, immb, Vn, Vd, Signedness::Unsigned); +} + bool TranslatorVisitor::UQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToUnsigned, Signedness::Unsigned); } From b7a76d6967f587d6c440cd617f9f9a4e0fd36d89 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 10 Apr 2019 15:20:09 -0400 Subject: [PATCH 3/3] simd_scalar_shift_by_immediate: Change UnallocatedEncoding() path in SaturatingShiftLeft to ReservedValue() Strictly speaking, immh being zero is defined as reserved in the ARMv8 reference manual. This was just an error on my part when introducing the SQSHL immediate scalar variant. --- .../A64/translate/impl/simd_scalar_shift_by_immediate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp index 5ecb8f1b..2cefc899 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp @@ -32,7 +32,7 @@ enum class FloatConversionDirection { bool SaturatingShiftLeft(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) { if (immh == 0b0000) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } const size_t esize = 8U << Common::HighestSetBit(immh.ZeroExtend());