From 7bce8d8757a512c48702c35811830f10345b2fb1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 11 May 2018 10:42:31 -0400 Subject: [PATCH] A64: Implement URSHR (scalar) and URSRA (scalar) Now that the utility function is all set up from implementing SRSRA, the unsigned variants can now be trivially implemented by modifying the utility function to perform a logical shift right instead of an arithmetical shift right for the unsigned case. --- src/frontend/A64/decoder/a64.inc | 4 +-- .../impl/simd_scalar_shift_by_immediate.cpp | 33 ++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index f8b4f018..4eec0016 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -480,8 +480,8 @@ INST(SHL_1, "SHL", "01011 //INST(FCVTZS_fix_1, "FCVTZS (vector, fixed-point)", "010111110IIIIiii111111nnnnnddddd") INST(USHR_1, "USHR", "011111110IIIIiii000001nnnnnddddd") INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd") -//INST(URSHR_1, "URSHR", "011111110IIIIiii001001nnnnnddddd") -//INST(URSRA_1, "URSRA", "011111110IIIIiii001101nnnnnddddd") +INST(URSHR_1, "URSHR", "011111110IIIIiii001001nnnnnddddd") +INST(URSRA_1, "URSRA", "011111110IIIIiii001101nnnnnddddd") INST(SRI_1, "SRI", "011111110IIIIiii010001nnnnnddddd") INST(SLI_1, "SLI", "011111110IIIIiii010101nnnnnddddd") //INST(SQSHLU_1, "SQSHLU", "011111110IIIIiii011001nnnnnddddd") 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 0181b565..dcb2b52e 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 @@ -40,14 +40,21 @@ static void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, V } static void RoundingShiftRight(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); const IR::U64 round_bit = v.ir.LogicalShiftRight(v.ir.LogicalShiftLeft(operand, v.ir.Imm8(64 - shift_amount)), v.ir.Imm8(63)); const IR::U64 result = [&] { - IR::U64 tmp = v.ir.Add(v.ir.ArithmeticShiftRight(operand, v.ir.Imm8(shift_amount)), round_bit); + const IR::U64 shifted = [&]() -> 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)); + }(); + + IR::U64 tmp = v.ir.Add(shifted, round_bit); if (behavior == ShiftExtraBehavior::Accumulate) { tmp = v.ir.Add(tmp, v.V_scalar(esize, Vd)); @@ -122,7 +129,7 @@ bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return ReservedValue(); } - RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None); + RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed); return true; } @@ -131,7 +138,7 @@ bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return ReservedValue(); } - RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate); + RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed); return true; } @@ -168,6 +175,24 @@ bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { return true; } +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; +} + +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; +} + bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { if (!immh.Bit<3>()) { return ReservedValue();