From e1b4ff1068e2e988dcc11101ae3fd471d332defb 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 b1b4487e4d4009000ccca9d9192049d8db5f4d8f 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 d932d8ce..5bdca7e8 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 7bc704210410e98c3554ba90e5527480f9d2f529 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());