From f00789e6f7c208fbaf1d19c266e88b57522f0d6d Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 8 May 2018 16:33:28 -0400
Subject: [PATCH] A64: Implement SABD

---
 src/frontend/A64/decoder/a64.inc                 |  2 +-
 .../A64/translate/impl/simd_three_same.cpp       | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc
index 9ea147e2..cddf2e03 100644
--- a/src/frontend/A64/decoder/a64.inc
+++ b/src/frontend/A64/decoder/a64.inc
@@ -714,7 +714,7 @@ INST(SSHL_2,                 "SSHL",                                      "0Q001
 //INST(SQRSHL_2,               "SQRSHL",                                    "0Q001110zz1mmmmm010111nnnnnddddd")
 INST(SMAX,                   "SMAX",                                      "0Q001110zz1mmmmm011001nnnnnddddd")
 INST(SMIN,                   "SMIN",                                      "0Q001110zz1mmmmm011011nnnnnddddd")
-//INST(SABD,                   "SABD",                                      "0Q001110zz1mmmmm011101nnnnnddddd")
+INST(SABD,                   "SABD",                                      "0Q001110zz1mmmmm011101nnnnnddddd")
 //INST(SABA,                   "SABA",                                      "0Q001110zz1mmmmm011111nnnnnddddd")
 INST(ADD_vector,             "ADD (vector)",                              "0Q001110zz1mmmmm100001nnnnnddddd")
 INST(CMTST_2,                "CMTST",                                     "0Q001110zz1mmmmm100011nnnnnddddd")
diff --git a/src/frontend/A64/translate/impl/simd_three_same.cpp b/src/frontend/A64/translate/impl/simd_three_same.cpp
index c5001da0..d9a82dba 100644
--- a/src/frontend/A64/translate/impl/simd_three_same.cpp
+++ b/src/frontend/A64/translate/impl/simd_three_same.cpp
@@ -73,6 +73,22 @@ bool TranslatorVisitor::CMGE_reg_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd)
     return true;
 }
 
+bool TranslatorVisitor::SABD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
+    if (size == 0b11) {
+        return ReservedValue();
+    }
+
+    const size_t datasize = Q ? 128 : 64;
+    const size_t esize = 8 << size.ZeroExtend();
+
+    const IR::U128 operand1 = V(datasize, Vn);
+    const IR::U128 operand2 = V(datasize, Vm);
+    const IR::U128 result = ir.VectorSignedAbsoluteDifference(esize, operand1, operand2);
+
+    V(datasize, Vd, result);
+    return true;
+}
+
 bool TranslatorVisitor::SMAX(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
     if (size == 0b11) {
         return ReservedValue();