From 3872ae034d1cf7da4643090ed276c3e83b07a8c2 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Sun, 18 Feb 2018 02:13:42 -0300
Subject: [PATCH] Add MLS (vector) instruction, fix mistake introduced on last
 commit

---
 Ryujinx/Cpu/AOpCodeTable.cs                        |  1 +
 Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs | 12 ++++++++++--
 Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs     | 11 ++++++++---
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs
index a3a8477eb7..e42136b8c7 100644
--- a/Ryujinx/Cpu/AOpCodeTable.cs
+++ b/Ryujinx/Cpu/AOpCodeTable.cs
@@ -203,6 +203,7 @@ namespace ChocolArm64
             Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeSimdMemReg));
             Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit,        typeof(AOpCodeSimdMemLit));
             Set("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V,         typeof(AOpCodeSimdReg));
+            Set("0x101110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mls_V,         typeof(AOpCodeSimdReg));
             Set("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
             Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
             Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
index 245862a6a9..d6ebcc3ffc 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
@@ -182,8 +182,7 @@ namespace ChocolArm64.Instruction
             EmitScalarTernaryRaOpF(Context, () =>
             {
                 Context.Emit(OpCodes.Mul);
-                Context.Emit(OpCodes.Neg);
-                Context.Emit(OpCodes.Add);
+                Context.Emit(OpCodes.Sub);
             });
         }
 
@@ -262,6 +261,15 @@ namespace ChocolArm64.Instruction
             });
         }
 
+        public static void Mls_V(AILEmitterCtx Context)
+        {
+            EmitVectorTernaryOpZx(Context, () =>
+            {
+                Context.Emit(OpCodes.Mul);
+                Context.Emit(OpCodes.Sub);
+            });
+        }
+
         public static void Mul_V(AILEmitterCtx Context)
         {
             EmitVectorBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
index e4cdc9c5e0..97f288161c 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
@@ -210,14 +210,14 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
 
-            EmitVectorOpByElemF(Context, Emit, Op.Index);
+            EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: false);
         }
 
         public static void EmitVectorTernaryOpByElemF(AILEmitterCtx Context, Action Emit)
         {
             AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
 
-            EmitVectorOpByElemF(Context, Emit, Op.Index);
+            EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: true);
         }
 
         public static void EmitVectorOpF(AILEmitterCtx Context, Action Emit, OperFlags Opers)
@@ -256,7 +256,7 @@ namespace ChocolArm64.Instruction
             }
         }
 
-        public static void EmitVectorOpByElemF(AILEmitterCtx Context, Action Emit, int Elem)
+        public static void EmitVectorOpByElemF(AILEmitterCtx Context, Action Emit, int Elem, bool Ternary)
         {
             AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
@@ -266,6 +266,11 @@ namespace ChocolArm64.Instruction
 
             for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++)
             {
+                if (Ternary)
+                {
+                    EmitVectorExtractF(Context, Op.Rd, Index, SizeF);
+                }
+
                 EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
                 EmitVectorExtractF(Context, Op.Rm, Elem,  SizeF);