Adding tests for the byte overload of Ssse3.Shuffle
authorTanner Gooding <tagoo@outlook.com>
Sun, 1 Jul 2018 15:06:46 +0000 (08:06 -0700)
committerTanner Gooding <tagoo@outlook.com>
Wed, 4 Jul 2018 18:18:12 +0000 (11:18 -0700)
tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Program.Ssse3.cs
tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r.csproj
tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_ro.csproj

index 81bdf1f..039e4d4 100644 (file)
@@ -263,6 +263,7 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
     ("HorizontalBinOpTest.template",  new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))",     ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[i1] != Math.Clamp((left[i3] - left[i3 + 1]), short.MinValue, short.MaxValue)",                    ["ValidateRemainingResults"] = "result[i2] != Math.Clamp((right[i3] - right[i3 + 1]), short.MinValue, short.MaxValue)"}),
     ("SimpleBinOpTest.template",      new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "MultiplyAddAdjacent",        ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))",                    ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != Math.Clamp(((right[1] * left[1]) + (right[0] * left[0])), short.MinValue, short.MaxValue)", ["ValidateRemainingResults"] = "result[i] != Math.Clamp(((right[(i * 2) + 1] * left[(i * 2) + 1]) + (right[i * 2] * left[i * 2])), short.MinValue, short.MaxValue)"}),
     ("SimpleBinOpTest.template",      new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "MultiplyHighRoundScale",     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))",     ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != (short)((((left[0] * right[0]) >> 14) + 1) >> 1)",                                          ["ValidateRemainingResults"] = "result[i] != (short)((((left[i] * right[i]) >> 14) + 1) >> 1)"}),
+    ("SimpleBinOpTest.template",      new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "Shuffle",                    ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",  ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))",                    ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))",                ["ValidateFirstResult"] = "result[0] != ((right[0] > 127) ? 0 : left[right[0] & 0x0F])",                                            ["ValidateRemainingResults"] = "result[i] != ((right[i] > 127) ? 0 : left[right[i] & 0x0F])"}),
     ("SimpleBinOpTest.template",      new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "Shuffle",                    ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))",     ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((right[0] < 0) ? 0 : left[right[0] & 0x0F])",                                              ["ValidateRemainingResults"] = "result[i] != ((right[i] < 0) ? 0 : left[right[i] & 0x0F])"}),
     ("SimpleBinOpTest.template",      new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "Sign",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue + 1, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != (right[0] < 0 ? (sbyte)(-left[0]) : (right[0] > 0 ? left[0] : 0))",                         ["ValidateRemainingResults"] = "result[i] != (right[i] < 0 ? (sbyte)(-left[i]) : (right[i] > 0 ? left[i] : 0))"}),
     ("SimpleBinOpTest.template",      new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "Sign",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue + 1, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != (right[0] < 0 ? (short)(-left[0]) : (right[0] > 0 ? left[0] : 0))",                         ["ValidateRemainingResults"] = "result[i] != (right[i] < 0 ? (short)(-left[i]) : (right[i] > 0 ? left[i] : 0))"}),
index bb22c09..c49a41a 100644 (file)
@@ -23,6 +23,7 @@ namespace JIT.HardwareIntrinsics.X86
                 ["HorizontalSubtractSaturate.Int16"] = HorizontalSubtractSaturateInt16,
                 ["MultiplyAddAdjacent.Int16"] = MultiplyAddAdjacentInt16,
                 ["MultiplyHighRoundScale.Int16"] = MultiplyHighRoundScaleInt16,
+                ["Shuffle.Byte"] = ShuffleByte,
                 ["Shuffle.SByte"] = ShuffleSByte,
                 ["Sign.SByte"] = SignSByte,
                 ["Sign.Int16"] = SignInt16,
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs
new file mode 100644 (file)
index 0000000..7363d61
--- /dev/null
@@ -0,0 +1,330 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx  *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file.                                             *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void ShuffleByte()
+        {
+            var test = new SimpleBinaryOpTest__ShuffleByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates basic functionality works, using Load
+                    test.RunBasicScenario_Load();
+
+                    // Validates basic functionality works, using LoadAligned
+                    test.RunBasicScenario_LoadAligned();
+                }
+
+                // Validates calling via reflection works, using Unsafe.Read
+                test.RunReflectionScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates calling via reflection works, using Load
+                    test.RunReflectionScenario_Load();
+
+                    // Validates calling via reflection works, using LoadAligned
+                    test.RunReflectionScenario_LoadAligned();
+                }
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works, using Unsafe.Read
+                test.RunLclVarScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // Validates passing a local works, using Load
+                    test.RunLclVarScenario_Load();
+
+                    // Validates passing a local works, using LoadAligned
+                    test.RunLclVarScenario_LoadAligned();
+                }
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__ShuffleByte
+    {
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+
+        private static Byte[] _data1 = new Byte[Op1ElementCount];
+        private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+        private static Vector128<Byte> _clsVar1;
+        private static Vector128<Byte> _clsVar2;
+
+        private Vector128<Byte> _fld1;
+        private Vector128<Byte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+        static SimpleBinaryOpTest__ShuffleByte()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+        }
+
+        public SimpleBinaryOpTest__ShuffleByte()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Ssse3.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            var result = Ssse3.Shuffle(
+                Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_Load()
+        {
+            var result = Ssse3.Shuffle(
+                Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunBasicScenario_LoadAligned()
+        {
+            var result = Ssse3.Shuffle(
+                Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+                Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_UnsafeRead()
+        {
+            var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+                                     .Invoke(null, new object[] {
+                                        Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+                                        Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Ssse3.Shuffle(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+            var result = Ssse3.Shuffle(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+            var result = Ssse3.Shuffle(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+            var result = Ssse3.Shuffle(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__ShuffleByte();
+            var result = Ssse3.Shuffle(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Ssse3.Shuffle(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario_UnsafeRead();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+        {
+            Byte[] inArray1 = new Byte[Op1ElementCount];
+            Byte[] inArray2 = new Byte[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Byte[] inArray1 = new Byte[Op1ElementCount];
+            Byte[] inArray2 = new Byte[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != ((right[0] > 127) ? 0 : left[right[0] & 0x0F]))
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if (result[i] != ((right[i] > 127) ? 0 : left[right[i] & 0x0F]))
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Ssse3)}.{nameof(Ssse3.Shuffle)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
index fc18de2..8f5763f 100644 (file)
@@ -38,6 +38,7 @@
     <Compile Include="HorizontalSubtractSaturate.Int16.cs" />
     <Compile Include="MultiplyAddAdjacent.Int16.cs" />
     <Compile Include="MultiplyHighRoundScale.Int16.cs" />
+    <Compile Include="Shuffle.Byte.cs" />
     <Compile Include="Shuffle.SByte.cs" />
     <Compile Include="Sign.SByte.cs" />
     <Compile Include="Sign.Int16.cs" />
index 8bad57d..0391fb6 100644 (file)
@@ -38,6 +38,7 @@
     <Compile Include="HorizontalSubtractSaturate.Int16.cs" />
     <Compile Include="MultiplyAddAdjacent.Int16.cs" />
     <Compile Include="MultiplyHighRoundScale.Int16.cs" />
+    <Compile Include="Shuffle.Byte.cs" />
     <Compile Include="Shuffle.SByte.cs" />
     <Compile Include="Sign.SByte.cs" />
     <Compile Include="Sign.Int16.cs" />