From 916540ff41446643a952fe7612aed16bae3fd7d8 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Fri, 30 Mar 2018 17:37:31 -0300
Subject: [PATCH] Fix EXT/Widening instruction carrying garbage values on some
 cases, fix ABD (it shouldn't accumulate, this is another variation of the
 instruction)

---
 .../Instruction/AInstEmitSimdArithmetic.cs    |  6 ++----
 .../Instruction/AInstEmitSimdHelper.cs        |  6 ++++++
 ChocolArm64/Instruction/AInstEmitSimdMove.cs  | 21 ++++++++++++-------
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 1d40ee8912..f2e80d2bd8 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -548,12 +548,12 @@ namespace ChocolArm64.Instruction
 
         public static void Uabd_V(AILEmitterCtx Context)
         {
-            EmitVectorTernaryOpZx(Context, () => EmitAbd(Context));
+            EmitVectorBinaryOpZx(Context, () => EmitAbd(Context));
         }
 
         public static void Uabdl_V(AILEmitterCtx Context)
         {
-            EmitVectorWidenRnRmTernaryOpZx(Context, () => EmitAbd(Context));
+            EmitVectorWidenRnRmBinaryOpZx(Context, () => EmitAbd(Context));
         }
 
         private static void EmitAbd(AILEmitterCtx Context)
@@ -563,8 +563,6 @@ namespace ChocolArm64.Instruction
             Type[] Types = new Type[] { typeof(long) };
 
             Context.EmitCall(typeof(Math).GetMethod(nameof(Math.Abs), Types));
-
-            Context.Emit(OpCodes.Add);
         }
 
         public static void Uaddl_V(AILEmitterCtx Context)
diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
index d8642e99a8..9a749ec68f 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
@@ -447,6 +447,9 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
+            Context.EmitLdvec(Op.Rd);
+            Context.EmitStvectmp();
+
             int Elems = 8 >> Op.Size;
 
             int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
@@ -489,6 +492,9 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
+            Context.EmitLdvec(Op.Rd);
+            Context.EmitStvectmp();
+
             int Elems = 8 >> Op.Size;
 
             int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
diff --git a/ChocolArm64/Instruction/AInstEmitSimdMove.cs b/ChocolArm64/Instruction/AInstEmitSimdMove.cs
index 3f427ad8ad..80f4178732 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdMove.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdMove.cs
@@ -61,6 +61,9 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdExt Op = (AOpCodeSimdExt)Context.CurrOp;
 
+            Context.EmitLdvec(Op.Rd);
+            Context.EmitStvectmp();
+
             int Bytes = Context.CurrOp.GetBitsCount() >> 3;
 
             int Position = Op.Imm4;
@@ -75,10 +78,12 @@ namespace ChocolArm64.Instruction
                 }
 
                 EmitVectorExtractZx(Context, Reg, Position++, 0);
-
-                EmitVectorInsert(Context, Op.Rd, Index, 0);
+                EmitVectorInsertTmp(Context, Index, 0);
             }
 
+            Context.EmitLdvectmp();
+            Context.EmitStvec(Op.Rd);
+
             if (Op.RegisterSize == ARegisterSize.SIMD64)
             {
                 EmitVectorZeroUpper(Context, Op.Rd);
@@ -113,7 +118,7 @@ namespace ChocolArm64.Instruction
 
             EmitVectorExtractZx(Context, Op.Rn, 0, 3);
 
-            EmitIntZeroHigherIfNeeded(Context);
+            EmitIntZeroUpperIfNeeded(Context);
 
             Context.EmitStintzr(Op.Rd);
         }
@@ -124,7 +129,7 @@ namespace ChocolArm64.Instruction
 
             EmitVectorExtractZx(Context, Op.Rn, 1, 3);
 
-            EmitIntZeroHigherIfNeeded(Context);
+            EmitIntZeroUpperIfNeeded(Context);
 
             Context.EmitStintzr(Op.Rd);
         }
@@ -135,7 +140,7 @@ namespace ChocolArm64.Instruction
 
             Context.EmitLdintzr(Op.Rn);
 
-            EmitIntZeroHigherIfNeeded(Context);
+            EmitIntZeroUpperIfNeeded(Context);
 
             EmitScalarSet(Context, Op.Rd, 3);
         }
@@ -146,7 +151,7 @@ namespace ChocolArm64.Instruction
 
             Context.EmitLdintzr(Op.Rn);
 
-            EmitIntZeroHigherIfNeeded(Context);
+            EmitIntZeroUpperIfNeeded(Context);
 
             EmitVectorInsert(Context, Op.Rd, 1, 3);
         }
@@ -301,7 +306,7 @@ namespace ChocolArm64.Instruction
             EmitVectorZip(Context, Part: 1);
         }
 
-        private static void EmitIntZeroHigherIfNeeded(AILEmitterCtx Context)
+        private static void EmitIntZeroUpperIfNeeded(AILEmitterCtx Context)
         {
             if (Context.CurrOp.RegisterSize == ARegisterSize.Int32)
             {
@@ -322,7 +327,7 @@ namespace ChocolArm64.Instruction
             for (int Index = 0; Index < Elems; Index++)
             {
                 int Elem = Part + ((Index & (Half - 1)) << 1);
-                
+
                 EmitVectorExtractZx(Context, Index < Half ? Op.Rn : Op.Rm, Elem, Op.Size);
 
                 EmitVectorInsert(Context, Op.Rd, Index, Op.Size);