diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Shared/GenerateTests.csx b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Shared/GenerateTests.csx index a2ba1d07e299fd..c89d19fa22cd21 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Shared/GenerateTests.csx +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Shared/GenerateTests.csx @@ -32,12 +32,15 @@ private static readonly (string templateFileName, Dictionary tem ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "Create", ["VectorType"] = "Vector64", ["BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != expectedValue" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "Create", ["VectorType"] = "Vector64", ["BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != expectedValue" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), + ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), + ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), + ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalar", ["VectorType"] = "Vector64", ["BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "resultElements[i] != 0" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalarUnsafe", ["VectorType"] = "Vector64", ["BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "false /* value is uninitialized */" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalarUnsafe", ["VectorType"] = "Vector64", ["BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "false /* value is uninitialized */" }), ("VectorCreateTest.template", new Dictionary { ["Isa"] = "Vector64", ["Method"] = "CreateScalarUnsafe", ["VectorType"] = "Vector64", ["BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "resultElements[0] != expectedValue", ["ValidateRemainingResults"] = "false /* value is uninitialized */" }), diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.Double.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.Double.cs new file mode 100644 index 00000000000000..4f898707ed3b61 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.Double.cs @@ -0,0 +1,106 @@ +// 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\General\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; + +namespace JIT.HardwareIntrinsics.General +{ + public static partial class Program + { + private static void CreateScalarDouble() + { + var test = new VectorCreate__CreateScalarDouble(); + + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class VectorCreate__CreateScalarDouble + { + private static readonly int LargestVectorSize = 8; + + private static readonly int ElementCount = Unsafe.SizeOf>() / sizeof(Double); + + public bool Succeeded { get; set; } = true; + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + Double value = TestLibrary.Generator.GetDouble(); + Vector64 result = Vector64.CreateScalar(value); + + ValidateResult(result, value); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + Double value = TestLibrary.Generator.GetDouble(); + object result = typeof(Vector64) + .GetMethod(nameof(Vector64.CreateScalar), new Type[] { typeof(Double) }) + .Invoke(null, new object[] { value }); + + ValidateResult((Vector64)(result), value); + } + + private void ValidateResult(Vector64 result, Double expectedValue, [CallerMemberName] string method = "") + { + Double[] resultElements = new Double[ElementCount]; + Unsafe.WriteUnaligned(ref Unsafe.As(ref resultElements[0]), result); + ValidateResult(resultElements, expectedValue, method); + } + + private void ValidateResult(Double[] resultElements, Double expectedValue, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (resultElements[0] != expectedValue) + { + succeeded = false; + } + else + { + for (var i = 1; i < ElementCount; i++) + { + if (resultElements[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"Vector64.CreateScalar(Double): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" value: {expectedValue}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", resultElements)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.Int64.cs new file mode 100644 index 00000000000000..68a182b74d6db7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.Int64.cs @@ -0,0 +1,106 @@ +// 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\General\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; + +namespace JIT.HardwareIntrinsics.General +{ + public static partial class Program + { + private static void CreateScalarInt64() + { + var test = new VectorCreate__CreateScalarInt64(); + + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class VectorCreate__CreateScalarInt64 + { + private static readonly int LargestVectorSize = 8; + + private static readonly int ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + public bool Succeeded { get; set; } = true; + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + Int64 value = TestLibrary.Generator.GetInt64(); + Vector64 result = Vector64.CreateScalar(value); + + ValidateResult(result, value); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + Int64 value = TestLibrary.Generator.GetInt64(); + object result = typeof(Vector64) + .GetMethod(nameof(Vector64.CreateScalar), new Type[] { typeof(Int64) }) + .Invoke(null, new object[] { value }); + + ValidateResult((Vector64)(result), value); + } + + private void ValidateResult(Vector64 result, Int64 expectedValue, [CallerMemberName] string method = "") + { + Int64[] resultElements = new Int64[ElementCount]; + Unsafe.WriteUnaligned(ref Unsafe.As(ref resultElements[0]), result); + ValidateResult(resultElements, expectedValue, method); + } + + private void ValidateResult(Int64[] resultElements, Int64 expectedValue, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (resultElements[0] != expectedValue) + { + succeeded = false; + } + else + { + for (var i = 1; i < ElementCount; i++) + { + if (resultElements[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"Vector64.CreateScalar(Int64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" value: {expectedValue}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", resultElements)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.UInt64.cs new file mode 100644 index 00000000000000..7316e1fd2b20e1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/CreateScalar.UInt64.cs @@ -0,0 +1,106 @@ +// 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\General\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; + +namespace JIT.HardwareIntrinsics.General +{ + public static partial class Program + { + private static void CreateScalarUInt64() + { + var test = new VectorCreate__CreateScalarUInt64(); + + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class VectorCreate__CreateScalarUInt64 + { + private static readonly int LargestVectorSize = 8; + + private static readonly int ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + public bool Succeeded { get; set; } = true; + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + UInt64 value = TestLibrary.Generator.GetUInt64(); + Vector64 result = Vector64.CreateScalar(value); + + ValidateResult(result, value); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + UInt64 value = TestLibrary.Generator.GetUInt64(); + object result = typeof(Vector64) + .GetMethod(nameof(Vector64.CreateScalar), new Type[] { typeof(UInt64) }) + .Invoke(null, new object[] { value }); + + ValidateResult((Vector64)(result), value); + } + + private void ValidateResult(Vector64 result, UInt64 expectedValue, [CallerMemberName] string method = "") + { + UInt64[] resultElements = new UInt64[ElementCount]; + Unsafe.WriteUnaligned(ref Unsafe.As(ref resultElements[0]), result); + ValidateResult(resultElements, expectedValue, method); + } + + private void ValidateResult(UInt64[] resultElements, UInt64 expectedValue, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (resultElements[0] != expectedValue) + { + succeeded = false; + } + else + { + for (var i = 1; i < ElementCount; i++) + { + if (resultElements[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"Vector64.CreateScalar(UInt64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" value: {expectedValue}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", resultElements)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/Program.Vector64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/Program.Vector64.cs index ae387c64e1ce1d..015f1eac55fded 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/Program.Vector64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/General/Vector64/Program.Vector64.cs @@ -23,12 +23,15 @@ static Program() ["Create.UInt32"] = CreateUInt32, ["Create.UInt64"] = CreateUInt64, ["CreateScalar.Byte"] = CreateScalarByte, + ["CreateScalar.Double"] = CreateScalarDouble, ["CreateScalar.Int16"] = CreateScalarInt16, ["CreateScalar.Int32"] = CreateScalarInt32, + ["CreateScalar.Int64"] = CreateScalarInt64, ["CreateScalar.SByte"] = CreateScalarSByte, ["CreateScalar.Single"] = CreateScalarSingle, ["CreateScalar.UInt16"] = CreateScalarUInt16, ["CreateScalar.UInt32"] = CreateScalarUInt32, + ["CreateScalar.UInt64"] = CreateScalarUInt64, ["CreateScalarUnsafe.Byte"] = CreateScalarUnsafeByte, ["CreateScalarUnsafe.Int16"] = CreateScalarUnsafeInt16, ["CreateScalarUnsafe.Int32"] = CreateScalarUnsafeInt32, diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 1ed0eb508c081a..72541afe5d7095 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -654,6 +654,24 @@ static Vector64 SoftwareFallback(byte value) } } + /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. + /// The value that element 0 will be initialized to. + /// A new instance with the first element initialized to and the remaining elements initialized to zero. + public static unsafe Vector64 CreateScalar(double value) + { + if (AdvSimd.IsSupported) + { + return Create(value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(double value) + { + return Unsafe.As>(ref value); + } + } + /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. /// The value that element 0 will be initialized to. /// A new instance with the first element initialized to and the remaining elements initialized to zero. @@ -694,6 +712,24 @@ static Vector64 SoftwareFallback(int value) } } + /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. + /// The value that element 0 will be initialized to. + /// A new instance with the first element initialized to and the remaining elements initialized to zero. + public static unsafe Vector64 CreateScalar(long value) + { + if (AdvSimd.Arm64.IsSupported) + { + return Create(value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(long value) + { + return Unsafe.As>(ref value); + } + } + /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. /// The value that element 0 will be initialized to. /// A new instance with the first element initialized to and the remaining elements initialized to zero. @@ -777,6 +813,26 @@ static Vector64 SoftwareFallback(uint value) } } + + /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. + /// The value that element 0 will be initialized to. + /// A new instance with the first element initialized to and the remaining elements initialized to zero. + [CLSCompliant(false)] + public static unsafe Vector64 CreateScalar(ulong value) + { + if (AdvSimd.Arm64.IsSupported) + { + return Create(value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(ulong value) + { + return Unsafe.As>(ref value); + } + } + /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized. /// The value that element 0 will be initialized to. /// A new instance with the first element initialized to and the remaining elements left uninitialized. diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 0402d19c1ff798..b2671a3bf530fd 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -273,8 +273,10 @@ public static partial class Vector64 [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 Create(ulong value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalar(byte value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 CreateScalar(double value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalar(short value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalar(int value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 CreateScalar(long value) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 CreateScalar(sbyte value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalar(float value) { throw null; } @@ -282,6 +284,8 @@ public static partial class Vector64 public static System.Runtime.Intrinsics.Vector64 CreateScalar(ushort value) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 CreateScalar(uint value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector64 CreateScalar(ulong value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalarUnsafe(byte value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalarUnsafe(short value) { throw null; } public static System.Runtime.Intrinsics.Vector64 CreateScalarUnsafe(int value) { throw null; }