diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index db10099f..865ab56d 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -478,7 +478,7 @@ INST(SHL_1, "SHL", "01011 //INST(SCVTF_fix_1, "SCVTF (vector, fixed-point)", "010111110IIIIiii111001nnnnnddddd") //INST(FCVTZS_fix_1, "FCVTZS (vector, fixed-point)", "010111110IIIIiii111111nnnnnddddd") INST(USHR_1, "USHR", "011111110IIIIiii000001nnnnnddddd") -//INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd") +INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd") //INST(URSHR_1, "URSHR", "011111110IIIIiii001001nnnnnddddd") //INST(URSRA_1, "URSRA", "011111110IIIIiii001101nnnnnddddd") //INST(SRI_1, "SRI", "011111110IIIIiii010001nnnnnddddd") 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 158c8870..3913f30f 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 @@ -8,18 +8,29 @@ namespace Dynarmic::A64 { -static void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { +enum class ShiftExtraBehavior { + None, + Accumulate, +}; + +static void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, + ShiftExtraBehavior behavior) { 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); - const IR::U64 result = [&] { + IR::U64 result = [&] { if (shift_amount == esize) { return v.ir.Imm64(0); } return v.ir.LogicalShiftRight(operand, v.ir.Imm8(shift_amount)); }(); + if (behavior == ShiftExtraBehavior::Accumulate) { + const IR::U64 addend = v.V_scalar(esize, Vd); + result = v.ir.Add(result, addend); + } + v.V_scalar(esize, Vd, result); } @@ -43,7 +54,16 @@ bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return ReservedValue(); } - ShiftRight(*this, immh, immb, Vn, Vd); + ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None); + return true; +} + +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); return true; }