From 34e1b030dd8cac475650591de4419ac470e7cbcd 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 8e58d157..2d71a7d0 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();