diff --git a/src/frontend/A64/translate/impl/simd_crypto_three_register.cpp b/src/frontend/A64/translate/impl/simd_crypto_three_register.cpp index 1ccca7de..e2f55bad 100644 --- a/src/frontend/A64/translate/impl/simd_crypto_three_register.cpp +++ b/src/frontend/A64/translate/impl/simd_crypto_three_register.cpp @@ -7,13 +7,13 @@ #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { - +namespace { enum class SM3TTVariant { A, B, }; -static void SM3TT1(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) { +bool SM3TT1(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) { const IR::U128 d = v.ir.GetQ(Vd); const IR::U128 m = v.ir.GetQ(Vm); const IR::U128 n = v.ir.GetQ(Vn); @@ -45,9 +45,10 @@ static void SM3TT1(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM const IR::U128 result = v.ir.VectorSetElement(32, tmp3, 3, final_tt1); v.ir.SetQ(Vd, result); + return true; } -static void SM3TT2(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) { +bool SM3TT2(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) { const IR::U128 d = v.ir.GetQ(Vd); const IR::U128 m = v.ir.GetQ(Vm); const IR::U128 n = v.ir.GetQ(Vn); @@ -79,26 +80,24 @@ static void SM3TT2(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM const IR::U128 result = v.ir.VectorSetElement(32, tmp3, 3, top_result); v.ir.SetQ(Vd, result); + return true; } +} // Anonymous namespace bool TranslatorVisitor::SM3TT1A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) { - SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A); - return true; + return SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A); } bool TranslatorVisitor::SM3TT1B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) { - SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B); - return true; + return SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B); } bool TranslatorVisitor::SM3TT2A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) { - SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A); - return true; + return SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A); } bool TranslatorVisitor::SM3TT2B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) { - SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B); - return true; + return SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B); } } // namespace Dynarmic::A64 diff --git a/src/frontend/A64/translate/impl/simd_permute.cpp b/src/frontend/A64/translate/impl/simd_permute.cpp index e190c602..73dfbe0e 100644 --- a/src/frontend/A64/translate/impl/simd_permute.cpp +++ b/src/frontend/A64/translate/impl/simd_permute.cpp @@ -14,8 +14,12 @@ enum class Transposition { TRN2, }; -void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, +bool VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Transposition type) { + if (!Q && size == 0b11) { + return v.ReservedValue(); + } + const size_t datasize = Q ? 128 : 64; const u8 esize = static_cast(8 << size.ZeroExtend()); @@ -61,6 +65,7 @@ void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, }(); v.V(datasize, Vd, result); + return true; } enum class UnzipType { @@ -68,7 +73,11 @@ enum class UnzipType { Odd, }; -void VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, UnzipType type) { +bool VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, UnzipType type) { + if (size == 0b11 && !Q) { + return v.ReservedValue(); + } + const size_t datasize = Q ? 128 : 64; const size_t esize = 8 << size.ZeroExtend(); @@ -86,43 +95,24 @@ void VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec } v.V(datasize, Vd, result); + return true; } } // Anonymous namespace bool TranslatorVisitor::TRN1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (!Q && size == 0b11) { - return ReservedValue(); - } - - VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN1); - return true; + return VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN1); } bool TranslatorVisitor::TRN2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (!Q && size == 0b11) { - return ReservedValue(); - } - - VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN2); - return true; + return VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN2); } bool TranslatorVisitor::UZP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (size == 0b11 && !Q) { - return ReservedValue(); - } - - VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even); - return true; + return VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even); } bool TranslatorVisitor::UZP2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (size == 0b11 && !Q) { - return ReservedValue(); - } - - VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd); - return true; + return VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd); } bool TranslatorVisitor::ZIP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { 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 238f2edc..700980f5 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 @@ -18,8 +18,12 @@ enum class Signedness { Unsigned, }; -void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, +bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, Signedness signedness) { + if (!immh.Bit<3>()) { + return v.ReservedValue(); + } + const size_t esize = 64; const u8 shift_amount = static_cast((esize * 2) - concatenate(immh, immb).ZeroExtend()); @@ -37,10 +41,15 @@ void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, } v.V_scalar(esize, Vd, result); + return true; } -void RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, +bool RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, Signedness signedness) { + if (!immh.Bit<3>()) { + return v.ReservedValue(); + } + const size_t esize = 64; const u8 shift_amount = static_cast((esize * 2) - concatenate(immh, immb).ZeroExtend()); @@ -64,6 +73,7 @@ void RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, }(); v.V_scalar(esize, Vd, result); + return true; } enum class ShiftDirection { @@ -71,8 +81,12 @@ enum class ShiftDirection { Right, }; -void ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, +bool ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftDirection direction) { + if (!immh.Bit<3>()) { + return v.ReservedValue(); + } + const size_t esize = 64; const u8 shift_amount = [&] { @@ -104,6 +118,7 @@ void ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec const IR::U64 result = v.ir.Or(v.ir.And(operand2, v.ir.Not(v.ir.Imm64(mask))), shifted); v.V_scalar(esize, Vd, result); + return true; } bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) { @@ -153,57 +168,27 @@ bool TranslatorVisitor::FCVTZU_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { } bool TranslatorVisitor::SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Left); - return true; + return ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Left); } bool TranslatorVisitor::SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Right); - return true; + return ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Right); } bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); - return true; + return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); } bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); - return true; + return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); } bool TranslatorVisitor::SSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); - return true; + return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); } bool TranslatorVisitor::SSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); - return true; + return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); } bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { @@ -222,39 +207,19 @@ bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { } bool TranslatorVisitor::URSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); - return true; + return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); } bool TranslatorVisitor::URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); - return true; + return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); } bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); - return true; + return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); } bool TranslatorVisitor::USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (!immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); - return true; + return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); } } // namespace Dynarmic::A64 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 8350e485..28cba14a 100644 --- a/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp @@ -8,7 +8,7 @@ #include "frontend/A64/translate/impl/impl.h" namespace Dynarmic::A64 { - +namespace { enum class ShiftExtraBehavior { None, Accumulate, @@ -20,8 +20,16 @@ enum class Signedness { Unsigned }; -static void ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, - ShiftExtraBehavior behavior, Signedness signedness) { +bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, + ShiftExtraBehavior behavior, Signedness signedness) { + if (immh == 0b0000) { + return v.DecodeError(); + } + + if (immh.Bit<3>() && !Q) { + return v.ReservedValue(); + } + const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); const size_t datasize = Q ? 128 : 64; @@ -41,10 +49,19 @@ static void ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, V } v.V(datasize, Vd, result); + return true; } -static void RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, - ShiftExtraBehavior behavior, Signedness signedness) { +bool RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, + ShiftExtraBehavior behavior, Signedness signedness) { + if (immh == 0b0000) { + return v.DecodeError(); + } + + if (!Q && immh.Bit<3>()) { + return v.ReservedValue(); + } + const size_t datasize = Q ? 128 : 64; const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); const u8 shift_amount = static_cast((esize * 2) - concatenate(immh, immb).ZeroExtend()); @@ -68,10 +85,19 @@ static void RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> } v.V(datasize, Vd, corrected_result); + return true; } -static void ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, - ShiftExtraBehavior behavior) { +bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, + ShiftExtraBehavior behavior) { + if (immh == 0b0000) { + return v.DecodeError(); + } + + if (immh.Bit<3>()) { + return v.ReservedValue(); + } + const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); const size_t source_esize = 2 * esize; const size_t part = Q ? 1 : 0; @@ -90,10 +116,19 @@ static void ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3 v.ir.VectorLogicalShiftRight(source_esize, operand, shift_amount)); v.Vpart(64, Vd, part, result); + return true; } -static void ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, - Signedness signedness) { +bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, + Signedness signedness) { + if (immh == 0b0000) { + return v.DecodeError(); + } + + if (immh.Bit<3>()) { + return v.ReservedValue(); + } + const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); const size_t datasize = 64; const size_t part = Q ? 1 : 0; @@ -110,56 +145,24 @@ static void ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb const IR::U128 result = v.ir.VectorLogicalShiftLeft(2 * esize, expanded_operand, shift_amount); v.V(2 * datasize, Vd, result); + return true; } +} // Anonymous namespace bool TranslatorVisitor::SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - if (immh.Bit<3>() && !Q) { - return ReservedValue(); - } - - ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); - return true; + return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); } bool TranslatorVisitor::SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - - if (!Q && immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); - return true; + return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); } bool TranslatorVisitor::SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - - if (!Q && immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); - return true; + return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); } bool TranslatorVisitor::SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - if (immh.Bit<3>() && !Q) { - return ReservedValue(); - } - - ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); - return true; + return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); } bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { @@ -182,103 +185,35 @@ bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) } bool TranslatorVisitor::SHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - - if (immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None); - return true; + return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None); } bool TranslatorVisitor::RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - - if (immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Round); - return true; + return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Round); } bool TranslatorVisitor::SSHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - if (immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed); - return true; + return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed); } bool TranslatorVisitor::URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - - if (!Q && immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); - return true; + return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); } bool TranslatorVisitor::URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - - if (!Q && immh.Bit<3>()) { - return ReservedValue(); - } - - RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); - return true; + return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); } bool TranslatorVisitor::USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - if (immh.Bit<3>() && !Q) { - return ReservedValue(); - } - - ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); - return true; + return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); } bool TranslatorVisitor::USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - if (immh.Bit<3>() && !Q) { - return ReservedValue(); - } - - ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); - return true; + return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); } bool TranslatorVisitor::USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { - if (immh == 0b0000) { - return DecodeError(); - } - if (immh.Bit<3>()) { - return ReservedValue(); - } - - ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned); - return true; + return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned); } bool TranslatorVisitor::SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { diff --git a/src/frontend/A64/translate/impl/simd_three_same.cpp b/src/frontend/A64/translate/impl/simd_three_same.cpp index 0e14e3d7..2cf94673 100644 --- a/src/frontend/A64/translate/impl/simd_three_same.cpp +++ b/src/frontend/A64/translate/impl/simd_three_same.cpp @@ -18,8 +18,12 @@ enum class ExtraBehavior { Round }; -static void HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, - HighNarrowingOp op, ExtraBehavior behavior) { +bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, + HighNarrowingOp op, ExtraBehavior behavior) { + if (size == 0b11) { + return v.ReservedValue(); + } + const size_t part = Q; const size_t esize = 8 << size.ZeroExtend(); const size_t doubled_esize = 2 * esize; @@ -43,6 +47,7 @@ static void HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Ve v.ir.VectorLogicalShiftRight(doubled_esize, wide, static_cast(esize))); v.Vpart(64, Vd, part, result); + return true; } enum class AbsDiffExtraBehavior { @@ -252,39 +257,19 @@ bool TranslatorVisitor::MUL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { } bool TranslatorVisitor::ADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (size == 0b11) { - return ReservedValue(); - } - - HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::None); - return true; + return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::None); } bool TranslatorVisitor::RADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (size == 0b11) { - return ReservedValue(); - } - - HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::Round); - return true; + return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::Round); } bool TranslatorVisitor::SUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (size == 0b11) { - return ReservedValue(); - } - - HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::None); - return true; + return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::None); } bool TranslatorVisitor::RSUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { - if (size == 0b11) { - return ReservedValue(); - } - - HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::Round); - return true; + return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::Round); } bool TranslatorVisitor::SHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { diff --git a/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp b/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp index 9abf2e5f..b0776509 100644 --- a/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp +++ b/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp @@ -23,8 +23,12 @@ enum class ExtraBehavior { Subtract, }; -void MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, +bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) { + if (size != 0b01 && size != 0b10) { + return v.UnallocatedEncoding(); + } + const auto [index, Vm] = Combine(size, H, L, M, Vmlo); const size_t idxdsize = H == 1 ? 128 : 64; const size_t esize = 8 << size.ZeroExtend(); @@ -42,34 +46,20 @@ void MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm< } v.V(datasize, Vd, result); + return true; } } // Anonymous namespace bool TranslatorVisitor::MLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { - if (size != 0b01 && size != 0b10) { - return UnallocatedEncoding(); - } - - MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate); - return true; + return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate); } bool TranslatorVisitor::MLS_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { - if (size != 0b01 && size != 0b10) { - return UnallocatedEncoding(); - } - - MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract); - return true; + return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract); } bool TranslatorVisitor::MUL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { - if (size != 0b01 && size != 0b10) { - return UnallocatedEncoding(); - } - - MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None); - return true; + return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None); } bool TranslatorVisitor::FMUL_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {