From 2d59d10ac88603ba57983bc725586642514426b7 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 12 Apr 2019 19:44:49 -0400 Subject: [PATCH] A64: Implement SQSHLU's vector variant The vector shift by immediate category is now fully implemented. --- src/frontend/A64/decoder/a64.inc | 2 +- .../impl/simd_shift_by_immediate.cpp | 24 +++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index e02bb2fa..2a3f888f 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -855,7 +855,7 @@ INST(URSHR_2, "URSHR", "0Q101 INST(URSRA_2, "URSRA", "0Q1011110IIIIiii001101nnnnnddddd") INST(SRI_2, "SRI", "0Q1011110IIIIiii010001nnnnnddddd") INST(SLI_2, "SLI", "0Q1011110IIIIiii010101nnnnnddddd") -//INST(SQSHLU_2, "SQSHLU", "0Q1011110IIIIiii011001nnnnnddddd") +INST(SQSHLU_2, "SQSHLU", "0Q1011110IIIIiii011001nnnnnddddd") INST(UQSHL_imm_2, "UQSHL (immediate)", "0Q1011110IIIIiii011101nnnnnddddd") INST(SQSHRUN_2, "SQSHRUN, SQSHRUN2", "0Q1011110IIIIiii100001nnnnnddddd") INST(SQRSHRUN_2, "SQRSHRUN, SQRSHRUN2", "0Q1011110IIIIiii100011nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp index 197740b0..3097da5e 100644 --- a/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp @@ -31,6 +31,12 @@ enum class Narrowing { SaturateToSigned, }; +enum class SaturatingShiftLeftType { + Signed, + Unsigned, + SignedWithUnsignedSaturation, +}; + enum class FloatConversionDirection { FixedToFloat, FloatToFixed, @@ -160,7 +166,7 @@ bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec V return true; } -bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) { +bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, SaturatingShiftLeftType type) { if (!Q && immh.Bit<3>()) { return v.ReservedValue(); } @@ -172,11 +178,15 @@ bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, const IR::U128 operand = v.V(datasize, Vn); const IR::U128 shift_vec = v.ir.VectorBroadcast(esize, v.I(esize, shift)); const IR::U128 result = [&] { - if (sign == Signedness::Signed) { + if (type == SaturatingShiftLeftType::Signed) { return v.ir.VectorSignedSaturatedShiftLeft(esize, operand, shift_vec); } - return v.ir.VectorUnsignedSaturatedShiftLeft(esize, operand, shift_vec); + if (type == SaturatingShiftLeftType::Unsigned) { + return v.ir.VectorUnsignedSaturatedShiftLeft(esize, operand, shift_vec); + } + + return v.ir.VectorSignedSaturatedShiftLeftUnsigned(esize, operand, shift_vec); }(); v.V(datasize, Vd, result); @@ -267,7 +277,11 @@ bool TranslatorVisitor::RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) } bool TranslatorVisitor::SQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, Signedness::Signed); + return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftType::Signed); +} + +bool TranslatorVisitor::SQSHLU_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { + return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftType::SignedWithUnsignedSaturation); } bool TranslatorVisitor::SQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { @@ -287,7 +301,7 @@ bool TranslatorVisitor::SQRSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec } bool TranslatorVisitor::UQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned); + return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftType::Unsigned); } bool TranslatorVisitor::UQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {