From 0e61ee6bf66dbc5739ee973da0d713d4f6cec413 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 8 May 2018 10:14:06 -0400
Subject: [PATCH] A64: Implement SHLL/SHLL2

---
 src/frontend/A64/decoder/a64.inc                   |  2 +-
 .../A64/translate/impl/simd_two_register_misc.cpp  | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc
index c286fecc..9ea147e2 100644
--- a/src/frontend/A64/decoder/a64.inc
+++ b/src/frontend/A64/decoder/a64.inc
@@ -623,7 +623,7 @@ INST(CMGE_zero_2,            "CMGE (zero)",                               "0Q101
 INST(CMLE_2,                 "CMLE (zero)",                               "0Q101110zz100000100110nnnnnddddd")
 INST(NEG_2,                  "NEG (vector)",                              "0Q101110zz100000101110nnnnnddddd")
 //INST(SQXTUN_2,               "SQXTUN, SQXTUN2",                           "0Q101110zz100001001010nnnnnddddd")
-//INST(SHLL,                   "SHLL, SHLL2",                               "0Q101110zz100001001110nnnnnddddd")
+INST(SHLL,                   "SHLL, SHLL2",                               "0Q101110zz100001001110nnnnnddddd")
 //INST(UQXTN_2,                "UQXTN, UQXTN2",                             "0Q101110zz100001010010nnnnnddddd")
 //INST(FCVTXN_2,               "FCVTXN, FCVTXN2",                           "0Q1011100z100001011010nnnnnddddd")
 //INST(FRINTA_1,               "FRINTA (vector)",                           "0Q10111001111001100010nnnnnddddd")
diff --git a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp
index f5f03b89..07a23b8c 100644
--- a/src/frontend/A64/translate/impl/simd_two_register_misc.cpp
+++ b/src/frontend/A64/translate/impl/simd_two_register_misc.cpp
@@ -281,4 +281,18 @@ bool TranslatorVisitor::SCVTF_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
     return true;
 }
 
+bool TranslatorVisitor::SHLL(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
+    if (size == 0b11) {
+        return ReservedValue();
+    }
+
+    const size_t esize = 8 << size.ZeroExtend();
+
+    const IR::U128 operand = ir.VectorZeroExtend(esize, Vpart(64, Vn, Q));
+    const IR::U128 result = ir.VectorLogicalShiftLeft(esize * 2, operand, static_cast<u8>(esize));
+
+    V(128, Vd, result);
+    return true;
+}
+
 } // namespace Dynarmic::A64