From 7ff280827b3b7b93ba14ad4597478f96a1be194c Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 10 Feb 2018 10:29:07 +0000 Subject: [PATCH] A64: Implement SIMD instructions USHLL, USHLL2 --- src/frontend/A64/decoder/a64.inc | 2 +- .../floating_point_conversion_integer.cpp | 4 ++-- src/frontend/A64/translate/impl/impl.cpp | 13 ++++++++++-- src/frontend/A64/translate/impl/impl.h | 8 ++++--- .../impl/simd_shift_by_immediate.cpp | 21 +++++++++++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 5fb3eb0f..e412fd2d 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -803,7 +803,7 @@ INST(SHL_2, "SHL", "0Q001 //INST(SQRSHRUN_2, "SQRSHRUN, SQRSHRUN2", "0Q1011110IIIIiii100011nnnnnddddd") //INST(UQSHRN_2, "UQSHRN, UQSHRN2", "0Q1011110IIIIiii100101nnnnnddddd") //INST(UQRSHRN_2, "UQRSHRN, UQRSHRN2", "0Q1011110IIIIiii100111nnnnnddddd") -//INST(USHLL, "USHLL, USHLL2", "0Q1011110IIIIiii101001nnnnnddddd") +INST(USHLL, "USHLL, USHLL2", "0Q1011110IIIIiii101001nnnnnddddd") //INST(UCVTF_fix_2, "UCVTF (vector, fixed-point)", "0Q1011110IIIIiii111001nnnnnddddd") //INST(FCVTZU_fix_2, "FCVTZU (vector, fixed-point)", "0Q1011110IIIIiii111111nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp index d6ed8dfc..44becf9a 100644 --- a/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp +++ b/src/frontend/A64/translate/impl/floating_point_conversion_integer.cpp @@ -125,9 +125,9 @@ bool TranslatorVisitor::FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm if (integer_to_float) { IR::U32U64 intval = X(intsize, static_cast(n)); - Vpart(fltsize, static_cast(d), part, intval); + Vpart_scalar(fltsize, static_cast(d), part, intval); } else { - IR::UAny fltval = Vpart(fltsize, static_cast(n), part); + IR::UAny fltval = Vpart_scalar(fltsize, static_cast(n), part); IR::U32U64 intval = ZeroExtend(fltval, intsize); X(intsize, static_cast(d), intval); } diff --git a/src/frontend/A64/translate/impl/impl.cpp b/src/frontend/A64/translate/impl/impl.cpp index 6a9d0f4a..64d6bd20 100644 --- a/src/frontend/A64/translate/impl/impl.cpp +++ b/src/frontend/A64/translate/impl/impl.cpp @@ -220,7 +220,16 @@ void TranslatorVisitor::V_scalar(size_t /*bitsize*/, Vec vec, IR::UAny value) { ir.SetQ(vec, ir.ZeroExtendToQuad(value)); } -IR::UAny TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) { +IR::U128 TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) { + ASSERT(part == 0 || part == 1); + ASSERT(bitsize == 64); + if (part == 0) { + return V(64, vec); + } + return ir.ZeroExtendToQuad(ir.VectorGetElement(bitsize, V(128, vec), part)); +} + +IR::UAny TranslatorVisitor::Vpart_scalar(size_t bitsize, Vec vec, size_t part) { ASSERT(part == 0 || part == 1); if (part == 0) { ASSERT(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64); @@ -230,7 +239,7 @@ IR::UAny TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) { return ir.VectorGetElement(bitsize, V(128, vec), part); } -void TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part, IR::UAny value) { +void TranslatorVisitor::Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::UAny value) { ASSERT(part == 0 || part == 1); if (part == 0) { ASSERT(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64); diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 6cc852ef..43c5d7b0 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -55,8 +55,10 @@ struct TranslatorVisitor final { IR::UAny V_scalar(size_t bitsize, Vec vec); void V_scalar(size_t bitsize, Vec vec, IR::UAny value); - IR::UAny Vpart(size_t bitsize, Vec vec, size_t part); - void Vpart(size_t bitsize, Vec vec, size_t part, IR::UAny value); + IR::U128 Vpart(size_t bitsize, Vec vec, size_t part); + + IR::UAny Vpart_scalar(size_t bitsize, Vec vec, size_t part); + void Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::UAny value); IR::UAnyU128 Mem(IR::U64 address, size_t size, AccType acctype); void Mem(IR::U64 address, size_t size, AccType acctype, IR::UAnyU128 value); @@ -877,7 +879,7 @@ struct TranslatorVisitor final { bool SQRSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool UQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool UQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool USHLL(bool Q, Imm<4> immh, Imm<3> immb, Reg Rn, Vec Vd); + bool USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool UCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool FCVTZU_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); 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 ad7a1b02..aad0735d 100644 --- a/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp @@ -28,4 +28,25 @@ bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) return true; } +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(); + } + const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); + const size_t datasize = 64; + const size_t part = Q ? 1 : 0; + + const u8 shift_amount = concatenate(immh, immb).ZeroExtend() - static_cast(esize); + + const IR::U128 operand = Vpart(datasize, Vn, part); + const IR::U128 expanded_operand = ir.VectorZeroExtend(esize, operand); + const IR::U128 result = ir.VectorLogicalShiftLeft(2 * esize, expanded_operand, shift_amount); + + V(2 * datasize, Vd, result); + return true; +} + } // namespace Dynarmic::A64