diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 865ab56d..eb26238d 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -467,7 +467,7 @@ INST(SUB_1, "SUB (vector)", "01111 //INST(SQRDMULH_vec_1, "SQRDMULH (vector)", "01111110zz1mmmmm101101nnnnnddddd") // Data Processing - FP and SIMD - SIMD Scalar shift by immediate -//INST(SSHR_1, "SSHR", "010111110IIIIiii000001nnnnnddddd") +INST(SSHR_1, "SSHR", "010111110IIIIiii000001nnnnnddddd") //INST(SSRA_1, "SSRA", "010111110IIIIiii000101nnnnnddddd") //INST(SRSHR_1, "SRSHR", "010111110IIIIiii001001nnnnnddddd") //INST(SRSRA_1, "SRSRA", "010111110IIIIiii001101nnnnnddddd") 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 3913f30f..0b8c0df4 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 @@ -13,15 +13,20 @@ enum class ShiftExtraBehavior { Accumulate, }; +enum class Signedness { + Signed, + Unsigned, +}; + static void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, - ShiftExtraBehavior behavior) { + ShiftExtraBehavior behavior, Signedness signedness) { const size_t esize = 64; const u8 shift_amount = static_cast((esize * 2) - concatenate(immh, immb).ZeroExtend()); const IR::U64 operand = v.V_scalar(esize, Vn); - IR::U64 result = [&] { - if (shift_amount == esize) { - return v.ir.Imm64(0); + IR::U64 result = [&]() -> IR::U64 { + if (signedness == Signedness::Signed) { + return v.ir.ArithmeticShiftRight(operand, v.ir.Imm8(shift_amount)); } return v.ir.LogicalShiftRight(operand, v.ir.Imm8(shift_amount)); }(); @@ -34,6 +39,15 @@ static void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, V v.V_scalar(esize, Vd, result); } +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; +} + bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { if (!immh.Bit<3>()) { return ReservedValue(); @@ -54,7 +68,7 @@ bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return ReservedValue(); } - ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None); + ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned); return true; } @@ -63,7 +77,7 @@ bool TranslatorVisitor::USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return ReservedValue(); } - ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate); + ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned); return true; }